home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / libs / phigs / ptk.lha / ptk / source / library / wind.c < prev   
Encoding:
C/C++ Source or Header  |  1992-10-01  |  148.0 KB  |  4,960 lines

  1. /*----------------------------------------------------------------------------
  2.  
  3.   Module name: PHIGS windows.
  4.  
  5.   Author: Gareth Williams.
  6.  
  7.   Function: This module contains functions for displaying PHIGS structures
  8.             in windows.
  9.  
  10.   Dependencies:
  11.  
  12.   Internal function list: 
  13.  
  14.   External function list: 
  15.  
  16.   Hashtables used: "structureid", "name", "label", "viewindex".
  17.  
  18.   Modification history: (Version), (Date), (name), (Description).
  19.  
  20.   1.0, 5th September 1991, G. Williams, First version.
  21.  
  22.   2.0, June 1992, G. Williams, Converted to ISO PHIGS C.
  23.  
  24. ----------------------------------------------------------------------------*/
  25.  
  26. #include <stdio.h>
  27. #include <math.h>
  28. #include <varargs.h>
  29. #ifdef SUN
  30. #include <string.h>
  31. #include <strings.h> 
  32. #endif
  33. #ifdef PEXSI
  34. #include <string.h>
  35. #include <strings.h> 
  36. #endif
  37. #include <phigs.h>
  38. #include "ptk.h"
  39.  
  40. /* constants */
  41.  
  42. #define PI      3.14159
  43.  
  44. /* data types */
  45.  
  46. #define ptkctmlinespace    0.008
  47.  
  48. #define ptkcfloatformat        20
  49.  
  50. typedef struct ptksterminal 
  51. {
  52.   Pint textstid;
  53.   Pint lines, columns, curr_colm, curr_line;
  54.   Pint visline;
  55.   Pfloat increment;
  56.   char floatformat[ptkcfloatformat];
  57.   char *lastline;
  58.   Pfloat realcols, reallines;
  59.   Pint txfont, txcolour;
  60. } ptksterminal;
  61.  
  62. typedef struct ptkswindow
  63. {
  64.   /* window variables */
  65.   Pint windowid;
  66.   Pint windowstid;
  67.   ptkewindowtype windowtype;
  68.   ptkewindowstate windowstate;
  69.   Pint iconstid;
  70.   Pint wsid;
  71.   Pint currentstid;
  72.   Pint windowname;
  73.   ptkboolean posted;
  74.   Pvisual_st viewstate;
  75.  
  76.   Pint windowviewind;
  77.   Ppoint windowsize;
  78.   Ppoint windowposition;
  79.   Ppoint iconsize;
  80.   Ppoint iconposition;
  81.   Ppoint framesize;
  82.   Pint usericon;
  83.   ptkboolean defaulticon;
  84.   Pint backgdcolour, edgecolour, frametlcolour, framebrcolour, bannercolour;
  85.   char titlestring[50];
  86.   Pfloat bannerheight;
  87.   Pint titlefont, titlecolour;
  88.  
  89.   Plimit3 viewlims, viewbox;
  90.   Ppoint3 viewvolume;
  91.   ptkecamerastate cameraswitch;
  92.  
  93.   /* camera variables */
  94.   Pfloat swivelangle, twistangle, spinangle;
  95.   Ppoint3 position; /* prp */
  96.   Ppoint3 ptinterest; /* vrp */
  97.   Ppoint3 positionaxis;
  98.   Ppoint3 ptinterestaxis;
  99.   Ppoint3 lastvpn, lastvup;
  100.   Pproj_type cameraproj;
  101.   Ppoint3 xaxis, yaxis;
  102.  
  103.   /* viewing variables */
  104.   Ppoint3 vrp, proj_ref_point;
  105.   Ppoint3 vpn, vup;
  106.   Plimit win;
  107.   Plimit3 proj_vp;
  108.   Pproj_type proj_type;
  109.   Pfloat viewplane, backplane, frontplane;
  110.   Pclip_ind clipxy, clipfront, clipback;
  111.   Plimit3 cliplimit;
  112.  
  113.   /* terminal window variables */
  114.   ptksterminal term;
  115.  
  116.   /* topology view area */
  117.   Plimit topviewarea;
  118.  
  119.   /* content window variables */
  120.   Pint range1, range2;
  121.   Pint viewrange1, viewrange2;
  122.  
  123.   /* next window */
  124.   struct ptkswindow *next;
  125. } ptkswindow;
  126.  
  127. typedef struct 
  128. {
  129.   ptkboolean postedwindows;
  130.   ptkswindow *frontptr;
  131.   ptkswindow *backptr;
  132. } ptkswswindow;
  133.  
  134. /*--------------------------------------------------------------------------*/
  135.  
  136. /* PHIGS viewing variables */
  137. static Ppoint3  vrp;
  138. static Ppoint3 vpn, vup;
  139. static Pview_map3 vmap;
  140.  
  141. static ptkswindow *windptr = NULL;
  142. static ptkswindow *firstwind = NULL;
  143. static ptkswindow *lastwind = NULL;
  144.  
  145. static Pint numwsids = 0;
  146. static Pint wsids[10];
  147. static ptkswswindow wswindows[10];
  148. static Pint windowcount = 0;
  149.  
  150. static Ppoint3 origin = {0.0, 0.0, 0.0};
  151.  
  152. /*--------------------------------------------------------------------------*/
  153.  
  154. static void setwindow(C(Pint) windid)
  155. PreANSI(Pint windid)
  156. {
  157.   ptkswindow *ptr;
  158.  
  159.   if (firstwind == NULL)
  160.   {
  161.     windptr = NULL;
  162.     return;
  163.   }
  164.   ptr = firstwind;
  165.   while (ptr->windowid != windid)
  166.   {
  167.     ptr = ptr->next;
  168.     if (ptr == NULL)
  169.     {
  170.       windptr = NULL;
  171.       return;
  172.     }
  173.   }
  174.   windptr = ptr;
  175. }  /* setwindow */
  176.  
  177. /*-------------------------------------------------------------------------*/
  178.  
  179. static ptkboolean getwindowid(C(Pint) windowstid, C(Pint *) windowid)
  180. PreANSI(Pint windowstid)
  181. PreANSI(Pint *windowid)
  182. {
  183.   ptkswindow *ptr;
  184.  
  185.   ptr = firstwind;
  186.   while (ptr->windowstid != windowstid)
  187.   {
  188.     ptr = ptr->next;
  189.     if (ptr == NULL)
  190.       return FALSE;
  191.   }
  192.   *windowid = ptr->windowid;
  193.   return TRUE;
  194. }  /* getwindowid */
  195.  
  196. /*--------------------------------------------------------------------------*/
  197.  
  198. static void findwsid(C(Pint) wsid, C(Pint *) ind)
  199. PreANSI(Pint wsid)
  200. PreANSI(Pint *ind)
  201. {
  202.   Pint i;
  203.  
  204.   *ind = -1;
  205.   for (i = 0; i < numwsids; i++)
  206.     if (wsids[i] == wsid)
  207.       *ind = i;
  208. }  /* findwsid */
  209.  
  210. /*--------------------------------------------------------------------------*/
  211.  
  212. static void checkws(C(Pint) wsid)
  213. PreANSI(Pint wsid)
  214. {
  215.   Pint ind;
  216.  
  217.   findwsid(wsid, &ind);
  218.   if (ind == -1)
  219.   {
  220.     wsids[numwsids] = wsid;
  221.     wswindows[numwsids].postedwindows = FALSE;
  222.     wswindows[numwsids].frontptr = NULL;
  223.     wswindows[numwsids].backptr = NULL;
  224.     numwsids++;
  225.   }
  226. }  /* checkws */
  227.  
  228. /*--------------------------------------------------------------------------*/
  229.  
  230. static ptkboolean iswindow(C(Pint) windstid, C(ptkswindow **) wptr)
  231. PreANSI(Pint windstid)
  232. PreANSI(ptkswindow **wptr)
  233. {
  234.   ptkswindow *ptr;
  235.   ptkboolean found;
  236.  
  237.   ptr = firstwind;
  238.   found = FALSE;
  239.   while ((ptr != NULL) && (!found))
  240.   {
  241.     if (ptr->currentstid == windstid)
  242.     {
  243.       *wptr = ptr;
  244.       found = TRUE;
  245.     }
  246.     else
  247.       ptr = ptr->next;
  248.   }
  249.   return found;
  250. }  /* iswindow */
  251.  
  252. /*--------------------------------------------------------------------------*/
  253.  
  254. static void findfront(C(Pint) wsid, C(ptkswswindow *) wsfront)
  255. PreANSI(Pint wsid)
  256. PreANSI(ptkswswindow *wsfront)
  257. {
  258.   Pposted_struct_list structlist;
  259.   Pint numstructs, error, i;
  260.   Pfloat priority;
  261.   ptkboolean found;
  262.   ptkswindow *wptr;
  263.  
  264.   found = FALSE;
  265.   priority = 0.0;
  266.   i = 0;
  267.   pinq_posted_structs(wsid, 0, 0, &error, &structlist, &numstructs);
  268.   structlist.postings = (Pposted_struct *)calloc(numstructs, 
  269.                                               sizeof(Pposted_struct));
  270.   pinq_posted_structs(wsid, numstructs, 0, &error, &structlist, &numstructs);
  271.   for (i = 0; i < numstructs; i++) 
  272.   {
  273.     /* find highest priority window structure */
  274.     if (iswindow(structlist.postings[i].id, &wptr))
  275.       if (structlist.postings[i].disp_pri > priority)
  276.       {
  277.         priority = structlist.postings[i].disp_pri;
  278.         wsfront->frontptr = wptr;
  279.         found = TRUE;
  280.       }
  281.   }
  282.   if (!found)
  283.     wsfront->postedwindows = FALSE;
  284. }  /* findfront */
  285.  
  286. /*--------------------------------------------------------------------------*/
  287.  
  288. static void findback(C(Pint) wsid, C(ptkswswindow *) wsback)
  289. PreANSI(Pint wsid)
  290. PreANSI(ptkswswindow *wsback)
  291. {
  292.   Pposted_struct_list structlist;
  293.   Pint numstructs, error, i;
  294.   Pfloat priority;
  295.   ptkboolean found;
  296.   ptkswindow *wptr;
  297.  
  298.   priority = 1.0;
  299.   pinq_posted_structs(wsid, 0, 0, &error, &structlist, &numstructs);
  300.   structlist.postings = (Pposted_struct *)calloc(numstructs, 
  301.                                               sizeof(Pposted_struct));
  302.   pinq_posted_structs(wsid, numstructs, 0, &error, &structlist, &numstructs);
  303.   for (i = 0; i < numstructs; i++) 
  304.   {
  305.     /* find lowest priority window structure */
  306.     if (iswindow(structlist.postings[i].id, &wptr))
  307.       if (structlist.postings[i].disp_pri < priority)
  308.       {
  309.         priority = structlist.postings[i].disp_pri;
  310.         wsback->backptr = wptr;
  311.         found = TRUE;
  312.       }
  313.   }
  314.   if (!found)
  315.     wsback->postedwindows = FALSE;
  316. }  /* findback */
  317.  
  318. /*--------------------------------------------------------------------------*/
  319.  
  320. static void setvalidwindowpos()
  321. {
  322.   Plimit lim;
  323.  
  324.   lim = ptk_limit(windptr->windowposition.x - (windptr->windowsize.x / 2.0), 
  325.                   windptr->windowposition.x + (windptr->windowsize.x / 2.0),
  326.                   windptr->windowposition.y - (windptr->windowsize.y / 2.0), 
  327.                   windptr->windowposition.y + (windptr->windowsize.y / 2.0) + 
  328.                   windptr->bannerheight);
  329.   if ((lim.x_min < 0.0) && (lim.y_min < 0.0))
  330.   {
  331.     /* bottom left */
  332.     windptr->windowposition.x += PTKMIN(1.0 - lim.x_max, -lim.x_min);
  333.     windptr->windowposition.y += PTKMIN(1.0 - lim.y_max, -lim.y_min);
  334.   }
  335.   else
  336.   if ((lim.x_min < 0.0) && (lim.y_max > 1.0))
  337.   {
  338.     /* top left */
  339.     windptr->windowposition.x += PTKMIN(1.0 - lim.x_max, -lim.x_min);
  340.     windptr->windowposition.y -= PTKMIN(lim.y_min, lim.y_max - 1.0);
  341.   }
  342.   else
  343.   if ((lim.x_max > 1.0) && (lim.y_min < 0.0))
  344.   {
  345.     /* bottom right */
  346.     windptr->windowposition.x -= PTKMIN(lim.x_min, lim.x_max - 1.0);
  347.     windptr->windowposition.y += PTKMIN(1.0 - lim.y_max, -lim.y_min);
  348.   }
  349.   else
  350.   if ((lim.x_max > 1.0) && (lim.y_max > 1.0))
  351.   {
  352.     /* top right */
  353.     windptr->windowposition.x -= PTKMIN(lim.x_min, lim.x_max - 1.0);
  354.     windptr->windowposition.y -= PTKMIN(lim.y_min, lim.y_max - 1.0);
  355.   }
  356.   else 
  357.   if (lim.x_min < 0.0)
  358.     windptr->windowposition.x += PTKMIN(1.0 - lim.x_max, -lim.x_min);
  359.   else
  360.   if (lim.x_max > 1.0)
  361.     windptr->windowposition.x -= PTKMIN(lim.x_min, lim.x_max - 1.0);
  362.   else
  363.   if (lim.y_min < 0.0)
  364.     windptr->windowposition.y += PTKMIN(1.0 - lim.y_max, -lim.y_min);
  365.   else
  366.   if (lim.y_max > 1.0)
  367.     windptr->windowposition.y -= PTKMIN(lim.y_min, lim.y_max - 1.0);
  368. }  /* setvalidwindowpos */
  369.  
  370. /*--------------------------------------------------------------------------*/
  371.  
  372. static void setvalidwindowsize()
  373. {
  374.   Plimit lim;
  375.  
  376.   lim = ptk_limit(windptr->windowposition.x - (windptr->windowsize.x / 2.0), 
  377.                   windptr->windowposition.x + (windptr->windowsize.x / 2.0),
  378.                   windptr->windowposition.y - (windptr->windowsize.y / 2.0), 
  379.                   windptr->windowposition.y + (windptr->windowsize.y / 2.0));
  380.   if (lim.x_min < 0.0)
  381.     lim.x_min = 0.0;
  382.   if (lim.x_max > 1.0)
  383.     lim.x_max = 1.0;
  384.   if (lim.y_min < 0.0)
  385.     lim.y_min = 0.0;
  386.   if (lim.y_max + windptr->bannerheight > 1.0)
  387.     lim.y_max = 1.0 - windptr->bannerheight;
  388.   windptr->windowposition = ptk_point(lim.x_min + (lim.x_max - lim.x_min) / 2.0,
  389.                                       lim.y_min + (lim.y_max - lim.y_min) / 2.0);
  390.   windptr->windowsize = ptk_point(lim.x_max - lim.x_min, lim.y_max - lim.y_min);
  391. }  /* setvalidwindowsize */
  392.  
  393. /*--------------------------------------------------------------------------*/
  394.  
  395. static void maxadjustlimits(C(Ppoint3 *) boundvolume)
  396. PreANSI(Ppoint3 *boundvolume)
  397. {
  398.   Pfloat  projht, projwt, aspectratio, maxdimen;
  399.  
  400.   /* calculate aspect ratio of window */
  401.   projht = windptr->viewlims.y_max - windptr->viewlims.y_min;
  402.   projwt = windptr->viewlims.x_max - windptr->viewlims.x_min;
  403.   aspectratio = PTKMAX(projht, projwt) / PTKMIN(projht, projwt);
  404.  
  405.   /* adjust view volume to have same aspect ratio as window */
  406.   maxdimen = PTKMAX(boundvolume->x, PTKMAX(boundvolume->y, boundvolume->z));
  407.   windptr->viewvolume = ptk_point3(maxdimen, maxdimen, maxdimen);
  408.  
  409.   if (projht == projwt)
  410.   {
  411.     if (maxdimen > boundvolume->y)
  412.       windptr->viewvolume.y *= aspectratio;
  413.     if (maxdimen > boundvolume->x)
  414.       windptr->viewvolume.x *= aspectratio;
  415.     if (maxdimen > boundvolume->z)
  416.       windptr->viewvolume.z *= aspectratio;
  417.   }
  418.   else
  419.   if (projht > projwt)
  420.     windptr->viewvolume.y *= aspectratio;
  421.   else
  422.   if (projht < projwt)
  423.     windptr->viewvolume.x *= aspectratio;
  424.  
  425.   /*
  426.   ** calculate zmax so that projection viewport has same
  427.   ** aspect ratio as view volume.
  428.   */
  429.  
  430.   windptr->viewlims.z_max = windptr->viewvolume.z * 
  431.                        (projht / windptr->viewvolume.y);
  432. }  /* maxadjustlimits */
  433.  
  434. /*--------------------------------------------------------------------------*/
  435.  
  436. static void adjustlimits(C(Ppoint3 *) viewvolume)
  437. PreANSI(Ppoint3 *viewvolume)
  438. {
  439.   Pfloat projht, projwt, winwt, winht, aspectratio, winaspectratio;
  440.   Pfloat diff, height;
  441.  
  442.   /* adjust view volume to have same aspect ratio as window */
  443.  
  444.   /* calculate aspect ratio of view area */
  445.   if ((viewvolume->y == 0.0) || (viewvolume->x == 0.0))
  446.     aspectratio = 1.0;
  447.   else
  448.     aspectratio = viewvolume->y / viewvolume->x;
  449.  
  450.   /* adjust projection viewport to have same aspect ratio as view volume */
  451.   windptr->viewbox = windptr->viewlims;
  452.   winht = windptr->viewbox.y_max - windptr->viewbox.y_min;
  453.   winwt = windptr->viewbox.x_max - windptr->viewbox.x_min;
  454.   if ((winht == 0.0) || (winwt == 0.0))
  455.     winaspectratio = 1.0;
  456.   else
  457.     winaspectratio = winht / winwt;    
  458.   if (aspectratio > winaspectratio)
  459.   {
  460.     /* decrease x */
  461.     diff = (winwt - ((1.0 / aspectratio) * winht));
  462.     windptr->viewbox.x_max -= diff / 2.0;
  463.     windptr->viewbox.x_min += diff / 2.0;
  464.   }
  465.   else
  466.   if (aspectratio < winaspectratio)
  467.   {
  468.     /* decrease y */
  469.     diff = (winht - (aspectratio * winwt));
  470.     windptr->viewbox.y_min += diff / 2.0;
  471.     windptr->viewbox.y_max -= diff / 2.0;
  472.   }       
  473.  
  474.   /*
  475.   ** calculate zmax so that projection viewport has same
  476.   ** aspect ratio as view volume.
  477.   */
  478.   height = windptr->viewbox.y_max - windptr->viewbox.y_min;
  479.   
  480.   if ((height == 0.0) || (viewvolume->y == 0.0))
  481.     windptr->viewbox.z_max = 1.0;
  482.   else
  483.     windptr->viewbox.z_max = PTKMIN(height, viewvolume->y) / 
  484.                           PTKMAX(height, viewvolume->y);
  485. }  /* adjustlimits */
  486.  
  487. /*--------------------------------------------------------------------------*/
  488.  
  489. static void evalviewvolume(C(Plimit3 *) wclimits, C(ptkboolean) docube)
  490. PreANSI(Plimit3 *wclimits)
  491. PreANSI(ptkboolean docube)
  492. {
  493.   Ppoint3 boundvolume, minbox, maxbox, centrebox, ptinterest, scale;
  494.   Pmatrix3 mat;
  495.   Ppoint3 pmin, pmax;
  496.   Pfloat diameter;
  497.  
  498.   minbox = ptk_point3(wclimits->x_min, wclimits->y_min, wclimits->z_min);
  499.   maxbox = ptk_point3(wclimits->x_max, wclimits->y_max, wclimits->z_max);
  500.  
  501.   /* find centre of limits */
  502.   centrebox = ptk_subv3(&maxbox, &minbox);
  503.   ptinterest = ptk_scalev3(¢rebox, 0.5);
  504.   ptinterest = ptk_addv3(&ptinterest, &minbox);
  505.   windptr->ptinterest = windptr->position = ptinterest;
  506.   centrebox = ptk_scalev3(&ptinterest, -0.5);
  507.   ptk_shift3(¢rebox, PTYPE_REPLACE, mat);
  508.  
  509.   if (docube)
  510.   {
  511.     /* increase box by 10 percent in all directions */
  512.     scale = ptk_point3(1.1, 1.1, 1.1);
  513.     ptk_scale3(&scale, PTYPE_POSTCONCAT, mat);
  514.   }
  515.  
  516.   centrebox = ptk_scalev3(¢rebox, -1.0);
  517.   ptk_shift3(¢rebox, PTYPE_POSTCONCAT, mat);        
  518.   minbox = ptk_transform3(mat, &minbox);
  519.   maxbox = ptk_transform3(mat, &maxbox); 
  520.  
  521.   /* bound volume is width, height and depth of limits */
  522.   boundvolume = ptk_subv3(&maxbox, &minbox);
  523.  
  524.   if (docube)
  525.   {
  526.     diameter = sqrt((boundvolume.x * boundvolume.x) +
  527.                     (boundvolume.y * boundvolume.y) +
  528.                     (boundvolume.z * boundvolume.z));
  529.     windptr->viewvolume = ptk_point3(diameter, diameter, diameter);
  530.   }
  531.   else
  532.     windptr->viewvolume = boundvolume;
  533.   adjustlimits(&windptr->viewvolume);
  534.   windptr->position.z += windptr->viewvolume.z;
  535. }  /* evalviewvolume */
  536.  
  537. /*--------------------------------------------------------------------------*/
  538.  
  539. static evalviewport(C(Plimit3 *) outview)
  540. PreANSI(Plimit3 *outview)
  541. {
  542.   Pfloat unitcube;
  543.   Ppoint origin;
  544.  
  545.   unitcube = PTKMIN(windptr->windowsize.x, windptr->windowsize.y);
  546.   outview->x_min *= unitcube;
  547.   outview->x_max *= unitcube;
  548.   outview->y_min *= unitcube;
  549.   outview->y_max *= unitcube;
  550.   outview->z_min *= unitcube;
  551.   outview->z_max *= unitcube;
  552.   origin = windptr->windowposition;
  553.   origin.x -= unitcube / 2.0;
  554.   origin.y -= unitcube / 2.0;
  555.   outview->x_min += origin.x;
  556.   outview->x_max += origin.x;
  557.   outview->y_min += origin.y;
  558.   outview->y_max += origin.y;
  559. }  /* evalviewport */
  560.  
  561. /*--------------------------------------------------------------------------*/
  562.  
  563. static void buildframe()
  564. /* build frame about the origin according to window size
  565. ** and frame size.
  566. */
  567. {
  568.   Ppoint3 pts[6], centre;
  569.   Ppoint centresize, bannercentre, bannerbox, framesize;
  570.   Pfloat charheight;
  571.   Ptext_align txalign;
  572.   Ppoint_list3 sets, ptlist;
  573.  
  574.   centre = ptk_point3(0.0, windptr->bannerheight / 2.0, 0.0);
  575.   centresize = windptr->windowsize;
  576.   centresize.y += windptr->bannerheight;
  577.   framesize = windptr->framesize;
  578.  
  579.   pts[0] = ptk_point3(centre.x - (centresize.x / 2.0) - framesize.x, 
  580.                       centre.y - (centresize.y / 2.0) - framesize.y,
  581.                       centre.z);
  582.   pts[1] = ptk_point3(pts[0].x, pts[0].y + centresize.y + (2.0 * framesize.y),
  583.                       centre.z);
  584.   pts[2] = ptk_point3(pts[0].x + centresize.x + (2.0 * framesize.x), pts[1].y,
  585.                       centre.z);
  586.   pts[3] = ptk_point3(pts[2].x - framesize.x, 
  587.                       pts[2].y - framesize.y, centre.z);
  588.   pts[4] = ptk_point3(pts[1].x + framesize.x, pts[3].y, 
  589.                       centre.z);
  590.   pts[5] = ptk_point3(pts[4].x, pts[0].y + framesize.y, 
  591.                       centre.z);
  592.   /* frame */
  593.   pset_pick_id(PTKEWINDOWFRAME);
  594.   pset_int_style(PSTYLE_SOLID);
  595.   pset_int_colr_ind(windptr->frametlcolour);
  596.   pts[2] = ptk_point3(pts[0].x + centresize.x + (2.0 * framesize.x), 
  597.                       pts[1].y, centre.z);
  598.   ptlist.num_points = 6;
  599.   ptlist.points = pts;
  600.   pfill_area3(&ptlist);
  601.   pset_int_colr_ind(windptr->framebrcolour);
  602.   pts[1].x += centresize.x + (2.0 * framesize.x);
  603.   pts[1].y -= centresize.y + (2.0 * framesize.y);
  604.   pts[4].x = pts[3].x;
  605.   pts[4].y = pts[5].y;
  606.   pfill_area3(&ptlist);
  607.  
  608.   /* view */
  609.   pset_pick_id(PTKEWINDOWVIEW);
  610.   pts[2] = ptk_point3(pts[3].x, pts[5].y, centre.z);
  611.   pts[4] = ptk_point3(pts[0].x + framesize.x, pts[3].y, 
  612.                       centre.z);
  613.   pset_int_style(PSTYLE_SOLID);
  614.   pset_int_colr_ind(windptr->backgdcolour);
  615.   pset_edge_flag(PEDGE_ON);
  616.   pset_edge_colr_ind(windptr->edgecolour);
  617.   sets.num_points = 4;
  618.   sets.points = &pts[2];
  619.   ptk_fillareaset3(1, &sets);
  620.  
  621.   /* banner */
  622.   pset_pick_id(PTKEWINDOWBANNER);
  623.   pts[0] = ptk_point3(-windptr->windowsize.x / 2.0, 
  624.                       windptr->windowsize.y /2.0, 0.0);
  625.   pts[1] = ptk_point3(pts[0].x, pts[0].y + windptr->bannerheight, 0.0);
  626.   pts[2] = ptk_point3(pts[0].x + windptr->windowsize.x, pts[1].y, 0.0);
  627.   pts[3] = ptk_point3(pts[2].x, pts[0].y, 0.0);
  628.   sets.num_points = 4;
  629.   sets.points = pts;
  630.   pset_int_colr_ind(windptr->bannercolour);
  631.   ptk_fillareaset3(1, &sets);
  632.   /* Implementation dependent bit - because HP doesn't support
  633.   ** INQUIRE TEXT EXTENT, kludge to size text in window banner.
  634.   */
  635. #ifdef SUN
  636.   bannerbox = ptk_point(windptr->windowsize.x, windptr->bannerheight);
  637. #endif
  638. #ifdef HP
  639.   bannerbox = ptk_point(windptr->windowsize.x, windptr->bannerheight * 0.7);
  640. #endif
  641. #ifdef PEXSI
  642.   bannerbox = ptk_point(windptr->windowsize.x, windptr->bannerheight * 0.7);
  643. #endif
  644.   ptk_computecharheight(windptr->wsid, windptr->titlestring, &bannerbox,
  645.                         windptr->titlefont, &charheight);
  646.   pset_char_ht(charheight);
  647.   txalign.hor = PHOR_CTR;
  648.   txalign.vert = PVERT_BOTTOM;
  649.   pset_text_align(&txalign);
  650.   pset_text_font(windptr->titlefont);
  651.   pset_text_colr_ind(windptr->titlecolour);
  652.   bannercentre = ptk_point(centre.x, windptr->windowsize.y / 2.0);
  653.   ptext(&bannercentre, windptr->titlestring); 
  654. }  /* buildframe */
  655.  
  656. /*--------------------------------------------------------------------------*/
  657.  
  658. static void buildicon()
  659. {
  660.   Ppoint3 boxpos;
  661.   Ppoint boxsize, framesize, iconbox, textpos;
  662.   char str[10];
  663.   Ptext_align align;
  664.   Pfloat charht;
  665.  
  666.   boxpos = ptk_point3(0.5, 0.5, 0.0);
  667.   boxsize = ptk_point(0.95, 0.95);
  668.   framesize = ptk_point(0.05, 0.05);
  669.   ptk_framebox(&boxpos, &boxsize, &framesize, windptr->backgdcolour,
  670.                  windptr->edgecolour, windptr->frametlcolour,
  671.                  windptr->framebrcolour);
  672.   sprintf(str, "%d", windptr->windowid);
  673.   textpos = ptk_point(0.175, 0.875);
  674.   align.hor = PHOR_CTR;
  675.   align.vert = PVERT_HALF;
  676.   pset_text_align(&align);
  677.   iconbox = ptk_point(0.15, 0.15);
  678.   ptk_computecharheight(windptr->wsid, str, &iconbox, 1, &charht);
  679.   pset_char_ht(charht);
  680.   pset_text_colr_ind(1);
  681.   ptext(&textpos, str); 
  682. }  /* buildicon */
  683.  
  684. /*--------------------------------------------------------------------------*/
  685.  
  686. static ptkboolean find_string(C(Pint) structure, C(char *) str)
  687. PreANSI(Pint structure)
  688. PreANSI(char *str)
  689. /*
  690. ** \parambegin
  691. ** \param{}{structure}{window structure id}{IN}
  692. ** \param{}{pickid}{item containing string}{IN}
  693. ** \param{}{strwindow}{string and window data}{IN}
  694. ** \paramend
  695. ** \blurb{Search for string in window items.
  696. ** Returns TRUE if string found, otherwise FALSE.}
  697. */
  698. {
  699.   Pint error, eltptr, numelems;
  700.   Psearch_status stat;
  701.   ptkselcontent elcont;
  702.   Pstore store;
  703.   ptkboolean stop_search, string_found;
  704.   Pelem_type_list include, exclude;
  705.   Pelem_type includeelems[10], excludeelems[10];
  706.  
  707.   eltptr = 0;
  708.   stop_search = FALSE;
  709.   string_found = FALSE;
  710.   numelems = ptk_elemcount(structure);
  711.   do 
  712.   {
  713.     includeelems[0] = PELEM_TEXT3;
  714.     includeelems[1] = PELEM_TEXT;
  715.     include.num_elem_types = 2;
  716.     include.elem_types = includeelems;
  717.     exclude.num_elem_types = 0;
  718.     exclude.elem_types = excludeelems;
  719.  
  720.     pelem_search(structure, eltptr, PDIR_FORWARD, &include, &exclude,
  721.                 &error, &stat, &eltptr);
  722.  
  723.     if (error != 0)
  724.       stop_search = TRUE;
  725.     else 
  726.     if (stat != PSEARCH_STATUS_SUCCESS) 
  727.       stop_search = TRUE;
  728.     else 
  729.     {
  730.       pcreate_store(&error, &store);
  731.       ptk_inqelemtypesizecontent(structure, eltptr, store, &error, 
  732.                                  &elcont);
  733.       if (error == 0) 
  734.       {
  735.         switch (elcont.eltype) 
  736.         {
  737.   
  738.           case PELEM_TEXT:
  739.             if (strcmp(elcont.eldata->text.char_string, str) == 0)
  740.               string_found = TRUE;
  741.             break;
  742.  
  743.           case PELEM_TEXT3:
  744.             if (strcmp(elcont.eldata->text3.char_string, str) == 0)
  745.               string_found = TRUE;
  746.             break;
  747.         }
  748.       }
  749.     }
  750.     eltptr++;
  751.     ptk_delstore(store);
  752.   } while (!string_found && !stop_search && (eltptr <= numelems));
  753.   return string_found;
  754. }  /* find_string */
  755.  
  756. /*--------------------------------------------------------------------------*/
  757.  
  758. static void updateframe()
  759. {
  760.   Ppoint3 wscale;
  761.   Pmatrix3 mat;
  762.   Ppoint position, size;
  763.   Ppoint3 shift;
  764.  
  765.   position = windptr->windowposition;
  766.   size = windptr->windowsize;
  767.   ptk_openstruct(windptr->windowstid);
  768.   ptk_seteditmode(PEDIT_REPLACE);
  769.   pset_elem_ptr(0);
  770.   pset_elem_ptr_label(ptk_stringtoint("label", "globaltran"));
  771.   poffset_elem_ptr(1);
  772.   shift = ptk_point3(position.x, position.y, 0.0);
  773.   ptk_shift3(&shift, PTYPE_REPLACE, mat);
  774.   pset_local_tran3(mat, PTYPE_REPLACE);
  775.   ptk_unseteditmode();
  776.   pdel_elems_labels(ptk_stringtoint("label", "begin-frame"), 
  777.                   ptk_stringtoint("label", "end-frame"));  
  778.   ptk_seteditmode(PEDIT_INSERT);  
  779.   buildframe();
  780.   ptk_unseteditmode();
  781.   ptk_closestruct();
  782.   windptr->viewbox = windptr->viewlims = 
  783.                       ptk_limit3(position.x - (size.x / 2.0),
  784.                                  position.x + (size.x / 2.0),
  785.                                  position.y - (size.y / 2.0),
  786.                                  position.y + (size.y / 2.0),
  787.                                  0.0, 1.0);
  788. }  /* updateframe */
  789.  
  790. /*--------------------------------------------------------------------------*/
  791.  
  792. static void do_structicon()
  793. {
  794.   /* build a spanner! */
  795.   static Ppoint spannerpts[7] = { {-0.05, 0.0}, {-0.05, 0.2},
  796.                   {-0.1, 0.27}, {-0.1, 0.33},
  797.                   {-0.05, 0.4}, {-0.05, 0.33}, 
  798.                                   {0.0, 0.3}};
  799.   Ppoint pts[28], *pts2, *pts3, scale, shift;
  800.   Ppoint_list ptlist;
  801.   Pmatrix3 mat;
  802.   Pint i;
  803.   
  804.   ptlist.num_points = 28;
  805.   ptlist.points = pts;
  806.   pts2 = &pts[7];
  807.   pts3 = &pts[14];
  808.   scale = ptk_point(-1.0, 1.0);
  809.   ptk_scale(&scale, PTYPE_REPLACE, mat);
  810.   for (i = 0; i < 7; i++)
  811.   {
  812.     pts[i] = spannerpts[i];
  813.     pts2[i] = ptk_transform(mat, &spannerpts[6 - i]);
  814.   }
  815.   scale = ptk_point(1.0, -1.0);
  816.   ptk_scale(&scale, PTYPE_REPLACE, mat);
  817.   for (i = 0; i < 7; i++)
  818.   {
  819.     pts3[i] = ptk_transform(mat, &pts2[6 - i]);
  820.     pts3[i + 7] = ptk_transform(mat, &spannerpts[6 - i]);  
  821.   }
  822.   shift = ptk_point(0.5, 0.5);
  823.   ptk_rotate(-45.0, PTKEZAXIS, PTYPE_REPLACE, mat);
  824.   ptk_shift(&shift, PTYPE_POSTCONCAT, mat);
  825.   for (i = 0; i < 28; i++)
  826.     pts[i] = ptk_transform(mat, &pts[i]);
  827.   ppolyline(&ptlist);
  828. }  /* do_structicon */
  829.  
  830. /*--------------------------------------------------------------------------*/
  831.  
  832. static void do_topologyicon()
  833. {
  834.   /* build a simple topology */
  835.   static Ppoint squarepts[5] = { {-0.075, -0.075}, {-0.075, 0.075},
  836.                  {0.075, 0.075}, {0.075, -0.075},
  837.                   {-0.075, -0.075}};
  838.   Ppoint pts[5], shift;
  839.   Ppoint_list ptlist;
  840.   Pmatrix3 mat;
  841.   Pint i;
  842.   
  843.   ptlist.num_points = 5;
  844.   ptlist.points = pts;
  845.  
  846.   shift = ptk_point(0.5, 0.65);
  847.   ptk_shift(&shift, PTYPE_REPLACE, mat);
  848.   for (i = 0; i < 5; i++)
  849.     pts[i] = ptk_transform(mat, &squarepts[i]);
  850.   ppolyline(&ptlist);
  851.  
  852.   shift = ptk_point(0.35, 0.35);
  853.   ptk_shift(&shift, PTYPE_REPLACE, mat);
  854.   for (i = 0; i < 5; i++)
  855.     pts[i] = ptk_transform(mat, &squarepts[i]);
  856.   ppolyline(&ptlist);
  857.  
  858.   shift = ptk_point(0.65, 0.35);
  859.   ptk_shift(&shift, PTYPE_REPLACE, mat);
  860.   for (i = 0; i < 5; i++)
  861.     pts[i] = ptk_transform(mat, &squarepts[i]);
  862.   ppolyline(&ptlist);
  863.  
  864.   ptlist.num_points = 3;
  865.   pts[0] = ptk_point(0.35, 0.425);
  866.   pts[1] = ptk_point(0.5, 0.575);
  867.   pts[2] = ptk_point(0.65, 0.425);
  868.   ppolyline(&ptlist);
  869. }  /* do_topologyicon */
  870.  
  871. /*--------------------------------------------------------------------------*/
  872.  
  873. static void do_terminalicon()
  874. {
  875.   /* a big T */
  876.   static char *str = "T";
  877.   Ppoint textpos, iconbox;
  878.   Pfloat charht;
  879.   Ptext_align align;
  880.   Pint textfont;
  881.  
  882.   /* Implementation dependent code, choose a nice font */
  883. #ifdef SUN
  884.   textfont = PFONT_COMPLEX;
  885. #endif
  886. #ifndef SUN
  887.   /* do for HP and PEXSI */
  888.   textfont = 1;
  889. #endif
  890.   textpos = ptk_point(0.5, 0.5);
  891.   align.hor = PHOR_CTR;
  892.   align.vert = PVERT_HALF;
  893.   pset_text_align(&align);
  894.   iconbox = ptk_point(0.8, 0.8);
  895.   /* Implementation dependent - fit "T" to icon box */
  896. #ifdef SUN
  897.   ptk_computecharheight(windptr->wsid, str, &iconbox, textfont, &charht);
  898.   pset_char_ht(charht);
  899. #endif
  900. #ifdef HP
  901.   pset_char_ht(0.7);
  902. #endif
  903. #ifdef PEXSI
  904.   pset_char_ht(0.7);
  905. #endif
  906.   pset_text_font(textfont);
  907.   ptext(&textpos, str); 
  908. }  /* do_terminalicon */
  909.  
  910. /*--------------------------------------------------------------------------*/
  911.  
  912. static void do_contenticon()
  913. {
  914.   /* build a simple content */
  915.   static Ppoint squarepts[5] = { {0.3, 0.3}, {0.3, 0.7},
  916.                  {0.7, 0.7}, {0.7, 0.3},
  917.                  {0.3, 0.3}};
  918.   Ppoint pts[2];
  919.   Ppoint_list ptlist;
  920.   
  921.   ptlist.num_points = 5;
  922.   ptlist.points = squarepts;
  923.   ppolyline(&ptlist);
  924.  
  925.   ptlist.num_points = 2;
  926.   ptlist.points = pts;
  927.   pts[0] = ptk_point(0.3, 0.4);
  928.   pts[1] = ptk_point(0.7, 0.4);
  929.   ppolyline(&ptlist);
  930.  
  931.   pts[0] = ptk_point(0.3, 0.5);
  932.   pts[1] = ptk_point(0.7, 0.5);
  933.   ppolyline(&ptlist);
  934.  
  935.   pts[0] = ptk_point(0.3, 0.6);
  936.   pts[1] = ptk_point(0.7, 0.6);
  937.   ppolyline(&ptlist);
  938. }  /* do_contenticon */
  939.  
  940. /*--------------------------------------------------------------------------*/
  941.  
  942. static void updateicon()
  943. {
  944.   Ppoint3 wscale, shift;
  945.   Pmatrix3 mat;
  946.  
  947.   if (windptr->defaulticon)
  948.   {
  949.     ptk_openstruct(windptr->iconstid);
  950.     ptk_seteditmode(PEDIT_REPLACE);
  951.     pset_elem_ptr(0);
  952.     pset_elem_ptr_label(ptk_stringtoint("label", "begin-icon"));
  953.     poffset_elem_ptr(-1);
  954.     shift = ptk_point3(-0.5, -0.5, 0.0);
  955.     ptk_shift3(&shift, PTYPE_REPLACE, mat);
  956.     wscale = ptk_point3(windptr->iconsize.x, windptr->iconsize.y, 1.0);
  957.     ptk_scale3(&wscale, PTYPE_POSTCONCAT, mat);
  958.     shift = ptk_point3(windptr->iconposition.x, windptr->iconposition.y, 
  959.                         0.0);
  960.     ptk_shift3(&shift, PTYPE_POSTCONCAT, mat);
  961.     pset_local_tran3(mat, PTYPE_REPLACE);
  962.     ptk_unseteditmode();
  963.     ptk_closestruct();
  964.   }
  965. }  /* updateicon */
  966.  
  967. /*--------------------------------------------------------------------------*/
  968.  
  969. static void updateview()
  970. {
  971.   Pint err;
  972.   Pview_rep3 vrep;
  973.   Plimit3 cliplims;
  974.  
  975.   ptk_pevalvieworientationmatrix3(&windptr->vrp, &windptr->vpn, 
  976.                     &windptr->vup, &err, vrep.ori_matrix);
  977.   vmap.proj_vp = windptr->proj_vp;
  978.   cliplims = windptr->cliplimit;
  979.   if ((windptr->windowtype == PTKESTRUCTWINDOW) ||
  980.       (windptr->windowtype == PTKETOPOLOGYWINDOW))  
  981.   {
  982.     evalviewport(&vmap.proj_vp);
  983.     evalviewport(&cliplims);
  984.   }
  985.   vrep.clip_limit = windptr->viewbox;
  986.   if (windptr->clipxy == PIND_CLIP)
  987.   {
  988.     vrep.clip_limit.x_min = cliplims.x_min;
  989.     vrep.clip_limit.x_max = cliplims.x_max;
  990.     vrep.clip_limit.y_min = cliplims.y_min;
  991.     vrep.clip_limit.y_max = cliplims.y_max;
  992.   }
  993.   if (windptr->clipfront == PIND_CLIP)
  994.     vrep.clip_limit.z_min = cliplims.z_min;
  995.   if (windptr->clipback == PIND_CLIP)
  996.     vrep.clip_limit.z_max = cliplims.z_max;
  997.   vrep.xy_clip = PIND_CLIP;
  998.   vrep.back_clip = vrep.front_clip = PIND_CLIP;
  999.   vmap.win = windptr->win;
  1000.   vmap.proj_type = windptr->proj_type;
  1001.   vmap.proj_ref_point = windptr->proj_ref_point;
  1002.   vmap.view_plane = windptr->viewplane;
  1003.   vmap.front_plane = windptr->frontplane;
  1004.   vmap.back_plane = windptr->backplane;
  1005.   peval_view_map_matrix3(&vmap, &err, vrep.map_matrix);
  1006.   if (windptr->windowstate == PTKEWINDOWOPEN)
  1007.     pset_view_rep3(windptr->wsid, windptr->windowviewind, &vrep);
  1008.   else
  1009.     windptr->viewstate = PVISUAL_ST_DEFER;
  1010. }  /* updateview */
  1011.  
  1012. /*--------------------------------------------------------------------------*/
  1013.  
  1014. static void updatecamera()
  1015. {
  1016.   Pint err;
  1017.   Pview_rep3 vrep;
  1018.   Pmatrix3 twistmat;
  1019.   Ppoint3 origin, initvpn, inittwist;
  1020.  
  1021.   vrp = windptr->ptinterest;
  1022.   vpn = ptk_subv3(&windptr->position, &vrp);
  1023.   vpn = ptk_unitv3(&vpn);
  1024.   ptk_rotatevv3(&windptr->lastvpn, &vpn, PTYPE_REPLACE, twistmat, &err);
  1025.   vup = ptk_transform3(twistmat, &windptr->lastvup);
  1026.   vup = ptk_unitv3(&vup);
  1027.   windptr->lastvup = vup;
  1028.   origin = ptk_point3(0.0, 0.0, 0.0);
  1029.   ptk_rotateline3(&origin, &vpn, windptr->twistangle, PTYPE_POSTCONCAT,
  1030.                   twistmat, &err);
  1031.   vup = ptk_transform3(twistmat, &vup);
  1032.   ptk_pevalvieworientationmatrix3(&vrp, &vpn, &vup, &err, vrep.ori_matrix);
  1033.   windptr->lastvpn = vpn;
  1034.   vrep.clip_limit = windptr->viewlims;
  1035.   vrep.xy_clip = PIND_CLIP;
  1036.   vrep.back_clip = vrep.front_clip = PIND_CLIP;
  1037.   vmap.win = ptk_limit(-windptr->viewvolume.x / 2.0, 
  1038.                         windptr->viewvolume.x / 2.0, 
  1039.                        -windptr->viewvolume.y / 2.0, 
  1040.                         windptr->viewvolume.y / 2.0);
  1041.   vmap.proj_vp = windptr->viewbox;
  1042.   vmap.proj_type = windptr->cameraproj;
  1043.   vmap.proj_ref_point = ptk_point3(0.0, 0.0, windptr->viewvolume.z);
  1044.   vmap.front_plane = windptr->viewvolume.z / 2.0;
  1045.   vmap.view_plane = 0.0;
  1046.   vmap.back_plane = -windptr->viewvolume.z / 2.0;
  1047.  
  1048.   peval_view_map_matrix3(&vmap, &err, vrep.map_matrix);
  1049.  
  1050.   if (windptr->windowstate == PTKEWINDOWOPEN)
  1051.     pset_view_rep3(windptr->wsid, windptr->windowviewind, &vrep);
  1052.   else
  1053.     windptr->viewstate = PVISUAL_ST_DEFER;
  1054. }  /* updatecamera */
  1055.  
  1056. /*--------------------------------------------------------------------------*/
  1057.  
  1058. static void updatewindowview()
  1059. {
  1060.   if (windptr->cameraswitch == PTKECAMERAON)
  1061.     updatecamera();
  1062.   else
  1063.     updateview();
  1064. }  /* updatewindowview */
  1065.  
  1066. /*--------------------------------------------------------------------------*/
  1067.  
  1068. static void initialiseterminal()
  1069. {
  1070.   Pfloat oneline;
  1071.  
  1072.   /* view mapping */
  1073.   windptr->proj_type = PTYPE_PARAL;
  1074.   windptr->proj_ref_point = ptk_point3(windptr->windowsize.x / 2.0,
  1075.                             windptr->windowsize.y / 2.0, 1.0);
  1076.   windptr->win = ptk_limit(0.0, windptr->windowsize.x, 0.0, 
  1077.                              windptr->windowsize.y);
  1078.   windptr->proj_vp = windptr->cliplimit = windptr->viewlims;
  1079.   windptr->backplane = windptr->viewplane = 0.0;
  1080.   windptr->frontplane = 1.0;
  1081.   /* view orientation */
  1082.   oneline = -windptr->windowsize.y/(Pfloat)windptr->term.lines;
  1083.   windptr->vrp = ptk_point3(0.0, -windptr->windowsize.y + 
  1084.                    (oneline * (Pfloat)(windptr->term.visline - 1)), 0.0);
  1085.   windptr->vpn = ptk_point3(0.0, 0.0, 1.0);
  1086.   windptr->vup = ptk_point3(0.0, 1.0, 0.0);
  1087.   /* set view rep */
  1088.   updateview();
  1089. }  /* initialiseterminal */
  1090.  
  1091. /*--------------------------------------------------------------------------*/
  1092. /*------------------------ Camera functions --------------------------------*/
  1093. /*--------------------------------------------------------------------------*/
  1094.  
  1095. /*function:external*/
  1096. extern void ptk_rotatecameraposition(C(Pint) windid, C(Pfloat) angle)
  1097. PreANSI(Pint windid) 
  1098. PreANSI(Pfloat angle)
  1099. /*
  1100. ** \parambegin
  1101. ** \param{Pint}{windid}{window identifier}{IN}
  1102. ** \param{Pfloat}{angle}{rotation angle in degrees}{IN}
  1103. ** \paramend 
  1104. ** \blurb{This function rotates the camera position in a circle centred
  1105. ** at the point of interest and about the axis defined by the function
  1106. ** {\tt ptk\_setpositionaxis}. The amount of rotation is {\tt angle}
  1107. ** degrees and the function is useful for rotating around an object.}
  1108. */
  1109. {
  1110.   Pmatrix3 spinmat, mat;
  1111.   Ppoint3 origin;
  1112.   Ppoint3 shiftprp;
  1113.   Pint err;
  1114.  
  1115.   setwindow(windid);
  1116.   if (windptr != NULL)
  1117.   {
  1118.     /* shift by -(vrp), rotate about arbitrary axis, shift by (vrp) */
  1119.     shiftprp = ptk_scalev3(&windptr->ptinterest, -1.0); 
  1120.     ptk_shift3(&shiftprp, PTYPE_REPLACE, spinmat);
  1121.     origin = ptk_point3(0.0, 0.0, 0.0);
  1122.     ptk_rotateline3(&origin, &windptr->positionaxis, 
  1123.                     angle, PTYPE_POSTCONCAT, spinmat, &err);
  1124.     ptk_shift3(&windptr->ptinterest, PTYPE_POSTCONCAT, spinmat);
  1125.     windptr->position = ptk_transform3(spinmat, &windptr->position);
  1126.     /* transform fixed x and y axes */
  1127.     ptk_rotateline3(&origin, &windptr->positionaxis, angle, 
  1128.                     PTYPE_REPLACE, mat, &err);
  1129.     windptr->xaxis = ptk_transform3(mat, &windptr->xaxis);
  1130.     windptr->yaxis = ptk_transform3(mat, &windptr->yaxis);
  1131.     updatecamera();
  1132.   }
  1133. }  /* ptk_rotatecameraposition */
  1134.  
  1135. /*--------------------------------------------------------------------------*/
  1136.  
  1137. /*function:external*/
  1138. extern void ptk_setpositionaxis(C(Pint) windid, C(Ppoint3 *) axis)
  1139. PreANSI(Pint windid)
  1140. PreANSI(Ppoint3 *axis)
  1141. /*
  1142. ** \parambegin
  1143. ** \param{Pint}{windid}{window identifier}{IN}
  1144. ** \param{Ppoint3 *}{axis}{axis of rotation}{IN}
  1145. ** \paramend 
  1146. ** \blurb{This function sets the axis of rotation for rotating 
  1147. ** the camera position using the function {\tt ptk\_rotatecameraposition}.}
  1148. */
  1149. {
  1150.   setwindow(windid);
  1151.   if (windptr != NULL)
  1152.     windptr->positionaxis = *axis;
  1153. }  /* ptk_setpositionaxis */
  1154.  
  1155. /*--------------------------------------------------------------------------*/
  1156.  
  1157. /*function:external*/
  1158. extern void ptk_setptinterestaxis(C(Pint) windid, C(Ppoint3 *) axis)
  1159. PreANSI(Pint windid)
  1160. PreANSI(Ppoint3 *axis)
  1161. /*
  1162. ** \parambegin
  1163. ** \param{Pint}{windid}{window identifier}{IN}
  1164. ** \param{Ppoint3 *}{axis}{axis of rotation}{IN}
  1165. ** \paramend 
  1166. ** \blurb{This function sets the axis of rotation for rotating 
  1167. ** the camera point of interest using the function
  1168. ** {\tt ptk\_rotatecameraptinterest}.}
  1169. */
  1170. {
  1171.   setwindow(windid);
  1172.   if (windptr != NULL)
  1173.     windptr->ptinterestaxis = *axis;
  1174. }  /* ptk_setptinterestaxis */
  1175.  
  1176. /*--------------------------------------------------------------------------*/
  1177.  
  1178. /*function:external*/
  1179. extern void ptk_scaleviewwindow(C(Pint) windid, C(Pfloat) scalefactor)
  1180. PreANSI(Pint windid) 
  1181. PreANSI(Pfloat scalefactor)
  1182. /*
  1183. ** \parambegin
  1184. ** \param{Pint}{windid}{window identifier}{IN}
  1185. ** \param{Pfloat}{scalefactor}{scale factor}{IN}
  1186. ** \paramend 
  1187. ** \blurb{This function scales the view window uniformly
  1188. ** by {\tt scalefactor}. A scalefactor in the range [0, 1] will
  1189. ** scale down the view window and create a zoom-in effect.
  1190. ** A scalefactor greater than 1.0 will give a zoom-out effect.}
  1191. */
  1192. {
  1193.   setwindow(windid);
  1194.   if (windptr != NULL)
  1195.   {
  1196.     if (scalefactor != 0.0)
  1197.     {
  1198.       windptr->viewvolume.x *= scalefactor;
  1199.       windptr->viewvolume.y *= scalefactor;
  1200.       updatecamera();
  1201.     }
  1202.   }
  1203. }  /* ptk_scaleviewwindow */
  1204.  
  1205. /*--------------------------------------------------------------------------*/
  1206.  
  1207. /*function:external*/
  1208. extern void ptk_rotatecameraptinterest(C(Pint) windid, C(Pfloat) angle)
  1209. PreANSI(Pint windid) 
  1210. PreANSI(Pfloat angle)
  1211. /*
  1212. ** \parambegin
  1213. ** \param{Pint}{windid}{window identifier}{IN}
  1214. ** \param{Pfloat}{angle}{rotation angle in degrees}{IN}
  1215. ** \paramend 
  1216. ** \blurb{This function rotates the camera point of interest in a circle 
  1217. ** centred at the camera position and about the axis defined by the function
  1218. ** {\tt ptk\_setptinterestaxis}. The amount of rotation is {\tt angle}
  1219. ** degrees and the function is useful for panning around a scene.}
  1220. */
  1221. {
  1222.   Pmatrix3 spinmat, mat;
  1223.   Ppoint3 origin;
  1224.   Ppoint3 shiftprp;
  1225.   Pint err;
  1226.  
  1227.   setwindow(windid);
  1228.   if (windptr != NULL)
  1229.   {
  1230.     /* shift by -(prp), rotate about arbitrary axis, shift by (prp) */
  1231.     shiftprp = ptk_scalev3(&windptr->position, -1.0);
  1232.     ptk_shift3(&shiftprp, PTYPE_REPLACE, spinmat);
  1233.     origin = ptk_point3(0.0, 0.0, 0.0);
  1234.     ptk_rotateline3(&origin, &windptr->ptinterestaxis, 
  1235.                     angle, PTYPE_POSTCONCAT, spinmat, &err);
  1236.     ptk_shift3(&windptr->position, PTYPE_POSTCONCAT, spinmat);
  1237.     windptr->ptinterest = ptk_transform3(spinmat, &windptr->ptinterest);
  1238.     /* transform fixed x and y axes */
  1239.     ptk_rotateline3(&origin, &windptr->ptinterestaxis, angle, 
  1240.                     PTYPE_REPLACE, mat, &err);
  1241.     windptr->xaxis = ptk_transform3(mat, &windptr->xaxis);
  1242.     windptr->yaxis = ptk_transform3(mat, &windptr->yaxis);
  1243.     updatecamera();
  1244.   }
  1245. }  /* ptk_rotatecameraptinterest */
  1246.  
  1247. /*--------------------------------------------------------------------------*/
  1248.  
  1249. /*function:external*/
  1250. extern void ptk_rotatecameraupvector(C(Pint) windid, C(Pfloat) angle)
  1251. PreANSI(Pint windid) 
  1252. PreANSI(Pfloat angle)
  1253. /*
  1254. ** \parambegin
  1255. ** \param{Pint}{windid}{window identifier}{IN}
  1256. ** \param{Pfloat}{angle}{rotation angle in degrees}{IN}
  1257. ** \paramend 
  1258. ** \blurb{This function rotates the camera up vector 
  1259. ** about the axis joining the camera position to the point of interest by
  1260. ** {\tt angle} degrees.}
  1261. */
  1262. {
  1263.   Pmatrix3 mat;
  1264.   Pint err;
  1265.   Ppoint3 zaxis;
  1266.  
  1267.   setwindow(windid);
  1268.   if (windptr != NULL)
  1269.   {
  1270.     /* rotate about z axis */
  1271.     windptr->twistangle += angle;
  1272.     zaxis = ptk_crossv3(&windptr->xaxis, &windptr->yaxis);
  1273.     ptk_rotateline3(&origin, &zaxis, angle, PTYPE_REPLACE, mat, &err);
  1274.     windptr->xaxis = ptk_transform3(mat, &windptr->xaxis);
  1275.     windptr->yaxis = ptk_transform3(mat, &windptr->yaxis);
  1276.     updatecamera();
  1277.   }
  1278. }  /* ptk_rotatecameraupvector */
  1279.  
  1280. /*--------------------------------------------------------------------------*/
  1281.  
  1282. /*function:external*/
  1283. extern void ptk_rotatepositionyaxis(C(Pint) windid, C(Pfloat) angle)
  1284. PreANSI(Pint windid) 
  1285. PreANSI(Pfloat angle)
  1286. /*
  1287. ** \parambegin
  1288. ** \param{Pint}{windid}{window identifier}{IN}
  1289. ** \param{Pfloat}{angle}{rotation angle in degrees}{IN}
  1290. ** \paramend 
  1291. ** \blurb{This function rotates the camera position in a circle centred
  1292. ** at the point of interest and about the y axis of a right-handed
  1293. ** coordinate system whose z axis is defined by the camera position and
  1294. ** point of interest.}
  1295. */
  1296. {
  1297.   Pmatrix3 mat;
  1298.   Pint err;
  1299.   Ppoint3 tempaxis;
  1300.  
  1301.   setwindow(windid);
  1302.   if (windptr != NULL)
  1303.   {
  1304.     ptk_inqpositionaxis(windid, &tempaxis, &err);
  1305.     ptk_setpositionaxis(windid, &windptr->yaxis);
  1306.     ptk_rotatecameraposition(windid, -angle);
  1307.     ptk_setpositionaxis(windid, &tempaxis);
  1308.   }
  1309. }  /* ptk_rotatepositionyaxis */
  1310.  
  1311. /*--------------------------------------------------------------------------*/
  1312.  
  1313. /*function:external*/
  1314. extern void ptk_rotatepositionxaxis(C(Pint) windid, C(Pfloat) angle)
  1315. PreANSI(Pint windid) 
  1316. PreANSI(Pfloat angle)
  1317. /*
  1318. ** \parambegin
  1319. ** \param{Pint}{windid}{window identifier}{IN}
  1320. ** \param{Pfloat}{angle}{rotation angle in degrees}{IN}
  1321. ** \paramend 
  1322. ** \blurb{This function rotates the camera position in a circle centred
  1323. ** at the point of interest and about the x axis of a right-handed
  1324. ** coordinate system whose z axis is defined by the camera position and
  1325. ** point of interest.}
  1326. */
  1327. {
  1328.   Pmatrix3 mat;
  1329.   Pint err;
  1330.   Ppoint3 tempaxis;
  1331.  
  1332.   setwindow(windid);
  1333.   if (windptr != NULL)
  1334.   {
  1335.     ptk_inqpositionaxis(windid, &tempaxis, &err);
  1336.     ptk_setpositionaxis(windid, &windptr->xaxis);
  1337.     ptk_rotatecameraposition(windid, -angle);
  1338.     ptk_setpositionaxis(windid, &tempaxis);
  1339.   }
  1340. }  /* ptk_rotatepositionxaxis */
  1341.  
  1342. /*--------------------------------------------------------------------------*/
  1343.  
  1344. /*function:external*/
  1345. extern void ptk_rotateptinterestyaxis(C(Pint) windid, C(Pfloat) angle)
  1346. PreANSI(Pint windid) 
  1347. PreANSI(Pfloat angle)
  1348. /*
  1349. ** \parambegin
  1350. ** \param{Pint}{windid}{window identifier}{IN}
  1351. ** \param{Pfloat}{angle}{rotation angle in degrees}{IN}
  1352. ** \paramend 
  1353. ** \blurb{This function rotates the camera point of interest
  1354. ** in a circle centred
  1355. ** at the camera position and about the y axis of a right-handed
  1356. ** coordinate system whose z axis is defined by the camera position and
  1357. ** point of interest.}
  1358. */
  1359. {
  1360.   Pmatrix3 mat;
  1361.   Pint err;
  1362.   Ppoint3 tempaxis;
  1363.  
  1364.   setwindow(windid);
  1365.   if (windptr != NULL)
  1366.   {
  1367.     ptk_inqptinterestaxis(windid, &tempaxis, &err);
  1368.     ptk_setptinterestaxis(windid, &windptr->yaxis);
  1369.     ptk_rotatecameraptinterest(windid, -angle);
  1370.     ptk_setptinterestaxis(windid, &tempaxis);
  1371.   }
  1372. }  /* ptk_rotateptinterestyaxis */
  1373.  
  1374. /*--------------------------------------------------------------------------*/
  1375.  
  1376. /*function:external*/
  1377. extern void ptk_rotateptinterestxaxis(C(Pint) windid, C(Pfloat) angle)
  1378. PreANSI(Pint windid) 
  1379. PreANSI(Pfloat angle)
  1380. /*
  1381. ** \parambegin
  1382. ** \param{Pint}{windid}{window identifier}{IN}
  1383. ** \param{Pfloat}{angle}{rotation angle in degrees}{IN}
  1384. ** \paramend 
  1385. ** \blurb{This function rotates the camera point of interest
  1386. ** in a circle centred
  1387. ** at the camera position and about the x axis of a right-handed
  1388. ** coordinate system whose z axis is defined by the camera position and
  1389. ** point of interest.}
  1390. */
  1391. {
  1392.   Pmatrix3 mat;
  1393.   Pint err;
  1394.   Ppoint3 tempaxis;
  1395.  
  1396.   setwindow(windid);
  1397.   if (windptr != NULL)
  1398.   {
  1399.     ptk_inqptinterestaxis(windid, &tempaxis, &err);
  1400.     ptk_setptinterestaxis(windid, &windptr->xaxis);
  1401.     ptk_rotatecameraptinterest(windid, -angle);
  1402.     ptk_setptinterestaxis(windid, &tempaxis);
  1403.   }
  1404. }  /* ptk_rotateptinterestxaxis */
  1405.  
  1406. /*--------------------------------------------------------------------------*/
  1407.  
  1408. /*function:external*/
  1409. extern void ptk_shiftcamera(C(Pint) windid, C(Ppoint3 *) shift)
  1410. PreANSI(Pint windid) 
  1411. PreANSI(Ppoint3 *shift)
  1412. /*
  1413. ** \parambegin
  1414. ** \param{Pint}{windid}{window identifier}{IN}
  1415. ** \param{Ppoint3 *}{shift}{shift factor}{IN}
  1416. ** \paramend 
  1417. ** \blurb{This function shifts the camera point of interest
  1418. ** and camera position about the axes of a right-handed
  1419. ** coordinate system whose z axis is defined by the camera position 
  1420. ** and point of interest.}
  1421. */
  1422. {
  1423.   Pmatrix3 mat;
  1424.   Pint err;
  1425.   Ppoint3 newshift;
  1426.  
  1427.   setwindow(windid);
  1428.   if (windptr != NULL)
  1429.   {
  1430.     ptk_0to3pt(&origin, &windptr->xaxis, &windptr->yaxis, PTYPE_REPLACE,
  1431.                mat);
  1432.     newshift = ptk_transform3(mat, shift);
  1433.     ptk_shift3(&newshift, PTYPE_REPLACE, mat);
  1434.     windptr->position = ptk_transform3(mat, &windptr->position);
  1435.     windptr->ptinterest = ptk_transform3(mat, &windptr->ptinterest);
  1436.     updatecamera();
  1437.   }
  1438. }  /* ptk_shiftcamera */
  1439.  
  1440. /*--------------------------------------------------------------------------*/
  1441.  
  1442. /*function:external*/
  1443. extern void ptk_setcameraposition(C(Pint) windid, C(Ppoint3 *) position)
  1444. PreANSI(Pint windid)
  1445. PreANSI(Ppoint3 *position)
  1446. /*
  1447. ** \parambegin
  1448. ** \param{Pint}{windid}{window identifier}{IN}
  1449. ** \param{Ppoint3 *}{position}{camera position}{IN}
  1450. ** \paramend 
  1451. ** \blurb{This function sets the camera position to {\tt position}
  1452. ** which is given in World Coordinates.}
  1453. */
  1454. {
  1455.   setwindow(windid);
  1456.   if (windptr != NULL)
  1457.   {
  1458.     windptr->position = *position;
  1459.     /* reset last vectors to defaults */
  1460.     windptr->lastvpn = ptk_point3(0.0, 0.0, 1.0);
  1461.     windptr->lastvup = ptk_point3(0.0, 1.0, 0.0);
  1462.     windptr->twistangle = 0.0;
  1463.     updatecamera();
  1464.   }
  1465. }  /* ptk_setcameraposition */
  1466.  
  1467. /*--------------------------------------------------------------------------*/
  1468.  
  1469. /*function:external*/
  1470. extern void ptk_setcameraptinterest(C(Pint) windid, C(Ppoint3 *) ptinterest)
  1471. PreANSI(Pint windid)
  1472. PreANSI(Ppoint3 *ptinterest)
  1473. /*
  1474. ** \parambegin
  1475. ** \param{Pint}{windid}{window identifier}{IN}
  1476. ** \param{Ppoint3 *}{ptinterest}{point of interest}{IN}
  1477. ** \paramend 
  1478. ** \blurb{This function sets the camera point of interest to
  1479. ** {\tt ptinterest} which is given in World Corrdinates.}
  1480. */
  1481. {
  1482.   setwindow(windid);
  1483.   if (windptr != NULL)
  1484.   {
  1485.     windptr->ptinterest = *ptinterest;
  1486.     updatecamera();
  1487.   }
  1488. }  /* ptk_setcameraptinterest */
  1489.  
  1490. /*--------------------------------------------------------------------------*/
  1491.  
  1492. /*function:external*/
  1493. extern void ptk_setcameraprojtype(C(Pint) windid, C(Pproj_type) proj)
  1494. PreANSI(Pint windid)
  1495. PreANSI(Pproj_type proj)
  1496. /*
  1497. ** \parambegin
  1498. ** \param{Pint}{windid}{window identifier}{IN}
  1499. ** \param{Pproj\_type}{proj}{camera projection type}{IN}
  1500. ** \paramend 
  1501. ** \blurb{This function sets the projection type of the view given by the
  1502. ** camera to PARALLEL or PERSPECTIVE. The default is PARALLEL.}
  1503. */
  1504. {
  1505.   setwindow(windid);
  1506.   if (windptr != NULL)
  1507.   {
  1508.     windptr->cameraproj = proj;
  1509.     updatecamera();
  1510.   }
  1511. }  /* ptk_setcameraprojtype */
  1512.   
  1513. /*--------------------------------------------------------------------------*/
  1514.   
  1515. /*function:external*/
  1516. extern void ptk_setcamerastate(C(Pint) windid, 
  1517.                                C(ptkecamerastate) cameraswitch)
  1518. PreANSI(Pint windid)
  1519. PreANSI(ptkecamerastate cameraswitch)
  1520. /*
  1521. ** \parambegin
  1522. ** \param{Pint}{windid}{window identifier}{IN}
  1523. ** \param{ptkecamerastate}{cameraswitch}{camera on or off}{IN}
  1524. ** \paramend 
  1525. ** \blurb{This function sets the camera of the window {\tt windid}
  1526. ** to ON or OFF. The default is ON.}
  1527. */
  1528. {
  1529.   setwindow(windid);
  1530.   if (windptr != NULL)
  1531.   {
  1532.     windptr->cameraswitch = cameraswitch;
  1533.     updatewindowview();
  1534.   }
  1535. }  /* ptk_setcamerastate */
  1536.  
  1537. /*--------------------------------------------------------------------------*/
  1538.  
  1539. /*function:external*/
  1540. extern void ptk_setcameraworld(C(Pint) windid, C(Pint_list *) stids)
  1541. PreANSI(Pint windid)
  1542. PreANSI(Pint_list *stids)
  1543. /*
  1544. ** \parambegin
  1545. ** \param{Pint}{windid}{window identifier}{IN}
  1546. ** \param{Pint\_list *}{stids}{structure identifier list}{IN}
  1547. ** \paramend 
  1548. ** \blurb{This function initialises the view volume of the camera so 
  1549. ** that it contains the combined bounding box of all the 
  1550. ** structures and structure networks in {\tt stids}. The camera position
  1551. ** and point of interest are set accordingly.}
  1552. */
  1553. {
  1554.   Pint i;
  1555.   Plimit3 cameraworld, stlimits;
  1556.  
  1557.   setwindow(windid);
  1558.   if (windptr != NULL)
  1559.   {
  1560.     cameraworld = ptk_limit3(10000.0, -10000.0, 10000.0, -10000.0, 10000.0,
  1561.                              -10000.0);
  1562.     for (i = 0; i < stids->num_ints; i++)
  1563.     {
  1564.       if (ptk_boundingbox(stids->ints[i], &stlimits, TRUE))
  1565.       {
  1566.         if (stlimits.x_min < cameraworld.x_min)
  1567.           cameraworld.x_min = stlimits.x_min;
  1568.         if (stlimits.y_min < cameraworld.y_min)
  1569.           cameraworld.y_min = stlimits.y_min;
  1570.         if (stlimits.z_min < cameraworld.z_min)
  1571.           cameraworld.z_min = stlimits.z_min;
  1572.         if (stlimits.x_max > cameraworld.x_max)
  1573.           cameraworld.x_max = stlimits.x_max;
  1574.         if (stlimits.y_max > cameraworld.y_max)
  1575.           cameraworld.y_max = stlimits.y_max;
  1576.         if (stlimits.z_max > cameraworld.z_max)
  1577.           cameraworld.z_max = stlimits.z_max;
  1578.       }
  1579.     }
  1580.     evalviewvolume(&cameraworld, TRUE);
  1581.     updatecamera();
  1582.   }
  1583. }  /* ptk_setcameraworld */
  1584.  
  1585. /*--------------------------------------------------------------------------*/
  1586.  
  1587. /*function:external*/
  1588. extern void ptk_setcameralimits(C(Pint) windid, C(Plimit3 *) limits,
  1589.                                 C(ptkboolean) adjust)
  1590. PreANSI(Pint windid)
  1591. PreANSI(Plimit3 *limits)
  1592. PreANSI(ptkboolean adjust)
  1593. /*
  1594. ** \parambegin
  1595. ** \param{Pint}{windid}{window identifier}{IN}
  1596. ** \param{Plimit3 *}{limits}{camera viewing limits in WC}{IN}
  1597. ** \param{ptkboolean}{adjust}{adjust given limits}{IN}
  1598. ** \paramend 
  1599. ** \blurb{This function initialises the view volume of the camera
  1600. ** to the specified bounding box given in World Coordinates. If 
  1601. ** {\tt adjust} is set to TRUE then the bounding box will be adjusted 
  1602. ** to be the bounding box of a sphere which encloses the original box.
  1603. ** The camera position and point of interest are set accordingly.}
  1604. */
  1605. {
  1606.   Pint i;
  1607.  
  1608.   setwindow(windid);
  1609.   if (windptr != NULL)
  1610.   {
  1611.     evalviewvolume(limits, adjust);
  1612.     updatecamera();
  1613.   }
  1614. }  /* ptk_setcameralimits */
  1615.  
  1616. /*--------------------------------------------------------------------------*/
  1617.  
  1618. /*function:external*/
  1619. extern void ptk_resetcamera(C(Pint) windid)
  1620. PreANSI(Pint windid)
  1621. /*
  1622. ** \parambegin
  1623. ** \param{Pint}{windid}{window identifier}{IN}
  1624. ** \paramend 
  1625. ** \blurb{This function resets the camera variables to their default
  1626. ** values. The camera view volume is left unchanged.}
  1627. */
  1628. {
  1629.   Pint i;
  1630.  
  1631.   setwindow(windid);
  1632.   if (windptr != NULL)
  1633.   {
  1634.     windptr->position = ptk_point3(0.5, 0.5, 2.0);
  1635.     windptr->ptinterest = ptk_point3(0.5, 0.5, 0.5);
  1636.     windptr->positionaxis = ptk_point3(0.0, 1.0, 0.0);
  1637.     windptr->ptinterestaxis = ptk_point3(0.0, 1.0, 0.0);
  1638.     windptr->lastvpn = ptk_point3(0.0, 0.0, 1.0);
  1639.     windptr->lastvup = ptk_point3(0.0, 1.0, 0.0);
  1640.     windptr->xaxis = ptk_point3(1.0, 0.0, 0.0);
  1641.     windptr->yaxis = ptk_point3(0.0, 1.0, 0.0);
  1642.     windptr->swivelangle = windptr->spinangle = 
  1643.     windptr->twistangle = 0.0;
  1644.     windptr->cameraproj = PTYPE_PARAL;
  1645.     if (windptr->cameraswitch == PTKECAMERAON)
  1646.       updatecamera();
  1647.   }
  1648. }  /* ptk_resetcamera */
  1649.  
  1650. /*--------------------------------------------------------------------------*/
  1651.  
  1652. /*function:external*/
  1653. extern void ptk_inqcameraposition(C(Pint) windid, C(Ppoint3 *) position,
  1654.                                   C(Pint *) err) 
  1655. PreANSI(Pint windid)
  1656. PreANSI(Ppoint3 *position)
  1657. PreANSI(Pint *err)
  1658. /*
  1659. ** \parambegin
  1660. ** \param{Pint}{windid}{window identifier}{IN}
  1661. ** \param{Ppoint3 *}{position}{camera position}{OUT}
  1662. ** \param{Pint *}{err}{error indicator}{OUT}
  1663. ** \paramend
  1664. ** \blurb{This function may be used to obtain the camera position in
  1665. ** World Coordinates.
  1666. ** The error code = 1 if {\tt windid} doesn't exist.}
  1667. */
  1668. {
  1669.   *err = 0;
  1670.   setwindow(windid);
  1671.   if (windptr != NULL)
  1672.     *position = windptr->position;
  1673.   else
  1674.     *err = 1;
  1675. }  /* ptk_inqcameraposition */
  1676.  
  1677. /*--------------------------------------------------------------------------*/
  1678.  
  1679. /*function:external*/
  1680. extern void ptk_inqcameraptinterest(C(Pint) windid, C(Ppoint3 *) ptinterest,
  1681.                                   C(Pint *) err) 
  1682. PreANSI(Pint windid)
  1683. PreANSI(Ppoint3 *ptinterest)
  1684. PreANSI(Pint *err)
  1685. /*
  1686. ** \parambegin
  1687. ** \param{Pint}{windid}{window identifier}{IN}
  1688. ** \param{Ppoint3 *}{ptinterest}{camera point of interest}{OUT}
  1689. ** \param{Pint *}{err}{error indicator}{OUT}
  1690. ** \paramend
  1691. ** \blurb{This function may be used to obtain the camera point of interest
  1692. ** in World Coordinates.
  1693. ** The error code = 1 if {\tt windid} doesn't exist.}
  1694. */
  1695. {
  1696.   *err = 0;
  1697.   setwindow(windid);
  1698.   if (windptr != NULL)
  1699.     *ptinterest = windptr->ptinterest;
  1700.   else
  1701.     *err = 1;
  1702. }  /* ptk_inqcameraptinterest */
  1703.  
  1704. /*--------------------------------------------------------------------------*/
  1705.  
  1706. /*function:external*/
  1707. extern void ptk_inqcameraprojtype(C(Pint) windid, C(Pproj_type *) projtype,
  1708.                                   C(Pint *) err) 
  1709. PreANSI(Pint windid)
  1710. PreANSI(Pproj_type *projtype)
  1711. PreANSI(Pint *err)
  1712. /*
  1713. ** \parambegin
  1714. ** \param{Pint}{windid}{window identifier}{IN}
  1715. ** \param{Pproj\_type *}{projtype}{camera projection type}{OUT}
  1716. ** \param{Pint *}{err}{error indicator}{OUT}
  1717. ** \paramend
  1718. ** \blurb{This function may be used to obtain the camera view projection
  1719. ** type which is either PARALLEL or PERSPECTIVE.
  1720. ** The error code = 1 if {\tt windid} doesn't exist.}
  1721. */
  1722. {
  1723.   *err = 0;
  1724.   setwindow(windid);
  1725.   if (windptr != NULL)
  1726.     *projtype = windptr->proj_type;
  1727.   else
  1728.     *err = 1;
  1729. }  /* ptk_inqcameraprojtype */
  1730.  
  1731. /*--------------------------------------------------------------------------*/
  1732.  
  1733. /*function:external*/
  1734. extern void ptk_inqcamerastate(C(Pint) windid, 
  1735.                   C(ptkecamerastate *) cameraswitch, C(Pint *) err) 
  1736. PreANSI(Pint windid)
  1737. PreANSI(ptkecamerastate *cameraswitch)
  1738. PreANSI(Pint *err)
  1739. /*
  1740. ** \parambegin
  1741. ** \param{Pint}{windid}{window identifier}{IN}
  1742. ** \param{ptkecamerastate *}{cameraswitch}{camera ON/OFF switch}{OUT}
  1743. ** \param{Pint *}{err}{error indicator}{OUT}
  1744. ** \paramend
  1745. ** \blurb{This function may be used to obtain the camera state which is
  1746. ** either ON or OFF.
  1747. ** The error code = 1 if {\tt windid} doesn't exist.}
  1748. */
  1749. {
  1750.   *err = 0;
  1751.   setwindow(windid);
  1752.   if (windptr != NULL)
  1753.     *cameraswitch = windptr->cameraswitch;
  1754.   else
  1755.     *err = 1;
  1756. }  /* ptk_inqcamerastate */
  1757.  
  1758. /*--------------------------------------------------------------------------*/
  1759.  
  1760. /*function:external*/
  1761. extern void ptk_inqcameralimits(C(Pint) windid, C(Plimit3 *) limits,
  1762.                                   C(Pint *) err) 
  1763. PreANSI(Pint windid)
  1764. PreANSI(Plimit3 *limits)
  1765. PreANSI(Pint *err)
  1766. /*
  1767. ** \parambegin
  1768. ** \param{Pint}{windid}{window identifier}{IN}
  1769. ** \param{Plimit3 *}{limits}{camera world limits}{OUT}
  1770. ** \param{Pint *}{err}{error indicator}{OUT}
  1771. ** \paramend
  1772. ** \blurb{This function may be used to obtain the camera view volume.
  1773. ** This defines the volume of a scene that the camera knows about
  1774. ** and is returned in World Coordinates.
  1775. ** The error code = 1 if {\tt windid} doesn't exist.}
  1776. */
  1777. {
  1778.   *err = 0;
  1779.   setwindow(windid);
  1780.   if (windptr != NULL)
  1781.   {
  1782.     *limits = ptk_limit3(windptr->ptinterest.x - windptr->viewvolume.x / 2.0,
  1783.                   windptr->ptinterest.x + windptr->viewvolume.x / 2.0,
  1784.                   windptr->ptinterest.y - windptr->viewvolume.y / 2.0,
  1785.                   windptr->ptinterest.y + windptr->viewvolume.y / 2.0,
  1786.                   windptr->ptinterest.z - windptr->viewvolume.z / 2.0,
  1787.                   windptr->ptinterest.z + windptr->viewvolume.z / 2.0);
  1788.   }
  1789.   else
  1790.     *err = 1;
  1791. }  /* ptk_inqcameralimits */
  1792.  
  1793. /*--------------------------------------------------------------------------*/
  1794.  
  1795. /*function:external*/
  1796. extern void ptk_inqpositionaxis(C(Pint) windid, C(Ppoint3 *) axis,
  1797.                                   C(Pint *) err) 
  1798. PreANSI(Pint windid)
  1799. PreANSI(Ppoint3 *axis)
  1800. PreANSI(Pint *err)
  1801. /*
  1802. ** \parambegin
  1803. ** \param{Pint}{windid}{window identifier}{IN}
  1804. ** \param{Ppoint3 *}{axis}{camera position axis of rotation}{OUT}
  1805. ** \param{Pint *}{err}{error indicator}{OUT}
  1806. ** \paramend
  1807. ** \blurb{This function may be used to obtain the axis of rotation
  1808. ** which is used to rotate the camera position in the function
  1809. ** {\tt ptk\_rotatecameraposition}.
  1810. ** The error code = 1 if {\tt windid} doesn't exist.}
  1811. */
  1812. {
  1813.   *err = 0;
  1814.   setwindow(windid);
  1815.   if (windptr != NULL)
  1816.     *axis = windptr->positionaxis;
  1817.   else
  1818.     *err = 1;
  1819. }  /* ptk_inqpositionaxis */
  1820.  
  1821. /*--------------------------------------------------------------------------*/
  1822.  
  1823. /*function:external*/
  1824. extern void ptk_inqptinterestaxis(C(Pint) windid, C(Ppoint3 *) axis,
  1825.                                   C(Pint *) err) 
  1826. PreANSI(Pint windid)
  1827. PreANSI(Ppoint3 *axis)
  1828. PreANSI(Pint *err)
  1829. /*
  1830. ** \parambegin
  1831. ** \param{Pint}{windid}{window identifier}{IN}
  1832. ** \param{Ppoint3 *}{axis}{camera point of interest axis of rotation}{OUT}
  1833. ** \param{Pint *}{err}{error indicator}{OUT}
  1834. ** \paramend
  1835. ** \blurb{This function may be used to obtain the axis of rotation
  1836. ** which is used to rotate the camera point of interest in the function
  1837. ** {\tt ptk\_rotatecameraptinterest}.
  1838. ** The error code = 1 if {\tt windid} doesn't exist.}
  1839. */
  1840. {
  1841.   *err = 0;
  1842.   setwindow(windid);
  1843.   if (windptr != NULL)
  1844.     *axis = windptr->ptinterestaxis;
  1845.   else
  1846.     *err = 1;
  1847. }  /* ptk_inqptinterestaxis */
  1848.  
  1849. /*--------------------------------------------------------------------------*/
  1850.  
  1851. /*function:external*/
  1852. extern void ptk_inqwindowviewrep(C(Pint) windid, C(Pview_rep3 *) rep,
  1853.                                   C(Pint *) err) 
  1854. PreANSI(Pint windid)
  1855. PreANSI(Pview_rep3 *rep)
  1856. PreANSI(Pint *err)
  1857. /*
  1858. ** \parambegin
  1859. ** \param{Pint}{windid}{window identifier}{IN}
  1860. ** \param{Pview\_rep3 *}{rep}{window view representation}{OUT}
  1861. ** \param{Pint *}{err}{error indicator}{OUT}
  1862. ** \paramend
  1863. ** \blurb{This function may be used to obtain the viewing parameters
  1864. ** which are used to set the window view when the camera is switched
  1865. ** OFF.
  1866. ** The error code = 1 if {\tt windid} doesn't exist.}
  1867. */
  1868. {
  1869.   Pview_map3 vmap;
  1870.  
  1871.   *err = 0;
  1872.   setwindow(windid);
  1873.   if (windptr != NULL)
  1874.   {
  1875.     ptk_pevalvieworientationmatrix3(&windptr->vrp, &windptr->vpn, 
  1876.                      &windptr->vup, err, rep->ori_matrix);
  1877.     vmap.proj_vp = windptr->proj_vp;
  1878.     vmap.win = windptr->win;
  1879.     vmap.proj_type = windptr->proj_type;
  1880.     vmap.proj_ref_point = windptr->proj_ref_point;
  1881.     vmap.view_plane = windptr->viewplane;
  1882.     vmap.front_plane = windptr->frontplane;
  1883.     vmap.back_plane = windptr->backplane;
  1884.     peval_view_map_matrix3(&vmap, err, rep->map_matrix);
  1885.     rep->clip_limit = windptr->cliplimit;
  1886.     rep->xy_clip = windptr->clipxy;
  1887.     rep->back_clip = windptr->clipback;
  1888.     rep->front_clip = windptr->clipfront;
  1889.   }
  1890.   else
  1891.     *err = 1;
  1892. }  /* ptk_inqwindowviewrep */
  1893.  
  1894. /*--------------------------------------------------------------------------*/
  1895. /*------------------------ Viewing functions -------------------------------*/
  1896. /*--------------------------------------------------------------------------*/
  1897.  
  1898. /*function:external*/
  1899. extern void ptk_setvieworientation3(C(Pint) windid, C(Ppoint3 *) vrp, 
  1900.             C(Ppoint3 *) vpn, C(Ppoint3 *) vup, C(Pint *) error)
  1901. PreANSI(Pint windid)
  1902. PreANSI(Ppoint3 *vrp)
  1903. PreANSI(Ppoint3 *vpn)
  1904. PreANSI(Ppoint3 *vup)
  1905. PreANSI(Pint *error)
  1906. /*
  1907. ** \parambegin
  1908. ** \param{Pint}{windid}{window identifier}{IN}
  1909. ** \param{Ppoint3 *}{vrp}{view reference point}{IN}
  1910. ** \param{Ppoint3 *}{vpn}{view plane normal}{IN}
  1911. ** \param{Ppoint3 *}{vup}{view up vector}{IN}
  1912. ** \param{Pint *}{error}{error indicator}{OUT}
  1913. ** \paramend 
  1914. ** \blurb{This function sets the window view orientation values. 
  1915. ** The camera must be switched OFF for these values to be set.
  1916. ** The error code is a standard PHIGS error code.}
  1917. */
  1918. {
  1919.   Pmatrix3 orimat;
  1920.  
  1921.   setwindow(windid);
  1922.   if (windptr != NULL)
  1923.   {
  1924.     ptk_pevalvieworientationmatrix3(vrp, vpn, vup, error, orimat);
  1925.     if (*error == 0)
  1926.     {
  1927.       windptr->vrp = *vrp;
  1928.       windptr->vpn = *vpn;
  1929.       windptr->vup = *vup;
  1930.       updateview();
  1931.     }
  1932.   }
  1933. }  /* ptk_setvieworientation3 */
  1934.  
  1935. /*--------------------------------------------------------------------------*/
  1936.  
  1937. /*function:external*/
  1938. extern void ptk_setviewmapping3(C(Pint) windid, C(Plimit *) window,
  1939.             C(Plimit3 *) viewport, C(Pproj_type) proj, C(Ppoint3 *) prp, 
  1940.             C(Pfloat) viewplane, C(Pfloat) backplane, C(Pfloat) frontplane, 
  1941.             C(Pint *) error)
  1942. PreANSI(Pint windid)
  1943. PreANSI(Plimit *window)
  1944. PreANSI(Plimit3 *viewport)
  1945. PreANSI(Pproj_type proj)
  1946. PreANSI(Ppoint3 *prp)
  1947. PreANSI(Pfloat viewplane)
  1948. PreANSI(Pfloat backplane)
  1949. PreANSI(Pfloat frontplane)
  1950. PreANSI(Pint *error)
  1951. /*
  1952. ** \parambegin
  1953. ** \param{Pint}{windid}{window identifier}{IN}
  1954. ** \param{Plimit *}{window}{view window}{IN}
  1955. ** \param{Plimit3 *}{viewport}{projection viewport}{IN}
  1956. ** \param{Pproj\_type}{proj}{projection type}{IN}
  1957. ** \param{Ppoint3 *}{prp}{projection reference point}{IN}
  1958. ** \param{Pfloat}{viewplane}{view plane distance}{IN}
  1959. ** \param{Pfloat}{backplane}{back plane distance}{IN}
  1960. ** \param{Pfloat}{frontplane}{front plane distance}{IN}
  1961. ** \param{Pint *}{error}{error indicator}{OUT}
  1962. ** \paramend 
  1963. ** \blurb{This function sets the window view mapping values.
  1964. ** The camera must be switched OFF for these values to be set.
  1965. ** The largest square within the window is defined to be the
  1966. ** device coordinates area which the view maps onto.
  1967. ** The error code is a standard PHIGS error code.}
  1968. */
  1969. {
  1970.   Pmatrix3 mapmat;
  1971.   Pview_map3 mapping;
  1972.  
  1973.   setwindow(windid);
  1974.   if (windptr != NULL)
  1975.   {
  1976.     mapping.win = *window;
  1977.     mapping.proj_type = proj;
  1978.     mapping.proj_ref_point = *prp;
  1979.     mapping.view_plane = viewplane;
  1980.     mapping.back_plane = backplane;
  1981.     mapping.front_plane = frontplane;
  1982.     mapping.proj_vp = *viewport;
  1983.     evalviewport(&mapping.proj_vp);
  1984.     peval_view_map_matrix3(&mapping, error, mapmat);
  1985.     if (*error == 0)
  1986.     {
  1987.       windptr->win = *window;
  1988.       windptr->proj_vp = *viewport;
  1989.       windptr->proj_type = proj;
  1990.       windptr->proj_ref_point = *prp;
  1991.       windptr->viewplane = viewplane;
  1992.       windptr->backplane = backplane;
  1993.       windptr->frontplane = frontplane;
  1994.       updateview();
  1995.     }
  1996.   }
  1997. }  /* ptk_setviewmapping3 */
  1998.  
  1999. /*--------------------------------------------------------------------------*/
  2000.  
  2001. /*function:external*/
  2002. extern void ptk_setviewclipping3(C(Pint) windid, C(Plimit3 *) cliplims,
  2003.             C(Pclip_ind) clipxy, C(Pclip_ind) clipback, C(Pclip_ind) clipfront)
  2004. PreANSI(Pint windid)
  2005. PreANSI(Plimit3 *cliplims)
  2006. PreANSI(Pclip_ind clipxy)
  2007. PreANSI(Pclip_ind clipfront)
  2008. PreANSI(Pclip_ind clipback)
  2009. /*
  2010. ** \parambegin
  2011. ** \param{Pint}{windid}{window identifier}{IN}
  2012. ** \param{Plimit3 *}{cliplims}{view clipping limits}{IN}
  2013. ** \param{Pclip\_ind}{clipxy}{x-y clipping indicator}{IN}
  2014. ** \param{Pclip\_ind}{clipback}{back plane clipping indicator}{IN}
  2015. ** \param{Pclip\_ind}{clipfront}{front plane clipping indicator}{IN}
  2016. ** \paramend 
  2017. ** \blurb{This function sets the window view clipping values. 
  2018. ** The camera must be switched OFF for these values to be set.}
  2019. */
  2020. {
  2021.   setwindow(windid);
  2022.   if (windptr != NULL)
  2023.   {
  2024.     windptr->cliplimit = *cliplims;
  2025.     windptr->clipxy = clipxy;
  2026.     windptr->clipback = clipback;
  2027.     windptr->clipfront = clipfront;
  2028.     updateview();
  2029.   }
  2030. }  /* ptk_setviewclipping3 */
  2031.  
  2032. /*--------------------------------------------------------------------------*/
  2033. /*------------------- Window system functions ------------------------------*/
  2034. /*--------------------------------------------------------------------------*/
  2035.  
  2036. static void createwindow(C(Pint) wsid, C(Pint) windid, C(Ppoint *) size,
  2037.                              C(Ppoint *) position, C(Pint) backgdcolour,
  2038.       C(Pint) edgecolour, C(Pint) frametlcolour, C(Pint) framebrcolour,
  2039.       C(Pint) titlecolour, C(char *) titlestring)
  2040. PreANSI(Pint wsid)
  2041. PreANSI(Pint windid)
  2042. PreANSI(Ppoint *size)
  2043. PreANSI(Ppoint *position)
  2044. PreANSI(Pint backgdcolour)
  2045. PreANSI(Pint edgecolour)
  2046. PreANSI(Pint frametlcolour)
  2047. PreANSI(Pint framebrcolour)
  2048. PreANSI(Pint titlecolour)
  2049. PreANSI(char *titlestring)
  2050. /* 
  2051. ** \parambegin
  2052. ** \param{Pint}{wsid}{workstation identifier}{IN}
  2053. ** \param{Pint}{windid}{window identifier}{IN}
  2054. ** \param{Ppoint *}{size}{window size}{IN}
  2055. ** \param{Ppoint *}{position}{window position}{IN}
  2056. ** \param{Pint}{backgdcolour}{background colour index of window}{IN}
  2057. ** \param{Pint}{edgecolour}{edge colour index of window}{IN}
  2058. ** \param{Pint}{frametlcolour}{top-left frame colour index}{IN}
  2059. ** \param{Pint}{framebrcolour}{bottom-right frame colour index}{IN}
  2060. ** \param{Pint}{titlecolour}{title string colour index}{IN}
  2061. ** \param{char *}{titlestring}{title string}{IN}
  2062. ** \paramend
  2063. ** \blurb{This function creates a window structure which may be used
  2064. ** for viewing PHIGS structures, PHIGS Toolkit topology diagrams and
  2065. ** PHIGS Toolkit structure content diagrams. A terminal window
  2066. ** type which contains only text. The window size and position are
  2067. ** given in the range [0, 1]. Each window has a virtual camera
  2068. ** which is useful for moving around a scene.}
  2069. */
  2070. {
  2071.   Pint err, inclname;
  2072.   Pview_rep3 vrep;
  2073.   char stname[30], str[10];
  2074.   Ppoint textpos, iconbox, boxsize, framesize;
  2075.   Pmatrix3 unitmat, mat;
  2076.   Ppoint3 wscale, shift, boxpos;
  2077.   Pfloat charht;
  2078.   Ptext_align align;
  2079.   Pint_list incl;
  2080.    
  2081.   setwindow(windid);
  2082.   if (windptr == NULL)
  2083.   {
  2084.     if (lastwind == NULL)
  2085.     {
  2086.       firstwind = lastwind = windptr =
  2087.         (ptkswindow *)malloc(sizeof(ptkswindow));
  2088.       windptr->next = NULL;
  2089.     }
  2090.     else
  2091.     {
  2092.       lastwind->next = windptr = (ptkswindow *)malloc(sizeof(ptkswindow));
  2093.       windptr->next = NULL;
  2094.       lastwind = lastwind->next;
  2095.     }
  2096.  
  2097.     windowcount++;  
  2098.     windptr->wsid = wsid;
  2099.     checkws(wsid);
  2100.     windptr->windowid = windid;
  2101.     sprintf(stname, "ptk$window%d", windid);
  2102.     windptr->windowstid = windptr->currentstid = 
  2103.                               ptk_stringtoint("structureid", stname);
  2104.     sprintf(stname, "ptk$icon%d", windid);
  2105.     windptr->iconstid = ptk_stringtoint("structureid", stname);
  2106.     sprintf(stname, "view$window%d", windid);
  2107.     windptr->windowviewind = ptk_stringtoint("viewindex", stname);
  2108.     sprintf(stname, "name$window%d", windid);
  2109.     windptr->windowname = ptk_stringtoint("name", stname);
  2110.     windptr->windowsize = *size;
  2111.     windptr->windowposition = *position;
  2112.   
  2113.     /* default camera variables */
  2114.     windptr->position = ptk_point3(0.5, 0.5, 2.0);
  2115.     windptr->ptinterest = ptk_point3(0.5, 0.5, 0.5);
  2116.     windptr->positionaxis = ptk_point3(0.0, 1.0, 0.0);
  2117.     windptr->ptinterestaxis = ptk_point3(0.0, 1.0, 0.0);
  2118.     windptr->lastvpn = ptk_point3(0.0, 0.0, 1.0);
  2119.     windptr->lastvup = ptk_point3(0.0, 1.0, 0.0);
  2120.     windptr->swivelangle = windptr->spinangle = 
  2121.     windptr->twistangle = 0.0;
  2122.     windptr->cameraproj = PTYPE_PARAL;
  2123.     windptr->xaxis = ptk_point3(1.0, 0.0, 0.0);
  2124.     windptr->yaxis = ptk_point3(0.0, 1.0, 0.0);
  2125.   
  2126.     /* default viewing variables */
  2127.     windptr->proj_type = PTYPE_PARAL;
  2128.     windptr->vrp = ptk_point3(0.5, 0.5, 0.5);
  2129.     windptr->proj_ref_point = ptk_point3(0.0, 0.0, 2.0);
  2130.     windptr->vpn = ptk_point3(0.0, 0.0, 1.0);
  2131.     windptr->vup = ptk_point3(0.0, 1.0, 0.0);
  2132.     windptr->win = ptk_limit(-0.5, 0.5, -0.5, 0.5);
  2133.     windptr->proj_vp = ptk_limit3(0.0, 1.0, 0.0, 1.0, 0.0, 1.0);
  2134.     windptr->frontplane = 0.5;
  2135.     windptr->viewplane = 0.0;
  2136.     windptr->backplane = -0.5;
  2137.     windptr->clipxy = windptr->clipfront = windptr->clipback = PIND_NO_CLIP;
  2138.   
  2139.     /* other window defaults */
  2140.     windptr->windowtype = PTKESTRUCTWINDOW;
  2141.     windptr->cameraswitch = PTKECAMERAON;
  2142.     windptr->framesize = ptk_point(0.01, 0.01);
  2143.     windptr->iconsize = ptk_point(0.1, 0.1);
  2144.     windptr->iconposition = windptr->windowposition;
  2145.     windptr->defaulticon = TRUE;
  2146.     windptr->titlefont = 1;
  2147.     windptr->bannerheight = 0.02;
  2148.     windptr->bannercolour = backgdcolour;
  2149.   
  2150.     windptr->backgdcolour = backgdcolour;
  2151.     windptr->edgecolour = edgecolour;
  2152.     windptr->frametlcolour = frametlcolour;
  2153.     windptr->framebrcolour = framebrcolour;
  2154.     windptr->titlecolour = titlecolour;
  2155.     strncpy(windptr->titlestring, titlestring, strlen(titlestring) + 1);
  2156.     windptr->posted = FALSE;
  2157.     windptr->windowstate = PTKEWINDOWOPEN;
  2158.     windptr->viewstate = PVISUAL_ST_CORRECT;
  2159.  
  2160.     windptr->viewbox = windptr->viewlims = windptr->cliplimit =
  2161.                         ptk_limit3(position->x - (size->x / 2.0),
  2162.                                    position->x + (size->x / 2.0),
  2163.                                    position->y - (size->y / 2.0),
  2164.                                    position->y + (size->y / 2.0),
  2165.                                    0.0, 1.0);
  2166.     windptr->viewvolume = ptk_point3(1.0, 1.0, 1.0);
  2167.   
  2168.     /* make window structure */
  2169.     ptk_seteditmode(PEDIT_INSERT);
  2170.     ptk_openstruct(windptr->windowstid);
  2171.  
  2172.     incl.num_ints = 1;
  2173.     incl.ints = &inclname;
  2174.     incl.ints[0] = windptr->windowname;
  2175.     padd_names_set(&incl);
  2176.  
  2177.     plabel(ptk_stringtoint("label", "globaltran"));
  2178.     /* window frame transformation */
  2179.     shift = ptk_point3(windptr->windowposition.x, windptr->windowposition.y, 
  2180.                         0.0); 
  2181.     ptk_shift3(&shift, PTYPE_REPLACE, mat);
  2182.     pset_local_tran3(mat, PTYPE_REPLACE);
  2183.   
  2184.     plabel(ptk_stringtoint("label", "begin-frame"));
  2185.     buildframe();
  2186.     plabel(ptk_stringtoint("label", "end-frame"));
  2187.  
  2188.     pset_int_style(PSTYLE_HOLLOW);
  2189.     pset_edge_flag(PEDGE_OFF);
  2190.     pset_edge_colr_ind(1);
  2191.     pset_int_colr_ind(1);
  2192.     pset_text_colr_ind(1);
  2193.     pset_char_ht(0.01);
  2194.     pset_text_font(1);
  2195.     align.hor = PHOR_NORM;
  2196.     align.vert = PVERT_NORM;
  2197.     pset_text_align(&align);
  2198.  
  2199.     ptk_unitmatrix3(mat);
  2200.     pset_local_tran3(mat, PTYPE_REPLACE);
  2201.     pset_view_ind(windptr->windowviewind);
  2202.   
  2203.     plabel(ptk_stringtoint("label", "begin-window"));
  2204.   
  2205.     plabel(ptk_stringtoint("label", "end-window"));
  2206.     premove_names_set(&incl);
  2207.     ptk_closestruct();
  2208.   
  2209.     updatecamera();
  2210.   
  2211.     /* make default window icon structure */
  2212.     ptk_openstruct(windptr->iconstid);
  2213.     padd_names_set(&incl);
  2214.     pset_pick_id(PTKEWINDOWICON);
  2215.     shift = ptk_point3(-0.5, -0.5, 0.0);
  2216.     ptk_shift3(&shift, PTYPE_REPLACE, mat);
  2217.     wscale.x = windptr->iconsize.x;
  2218.     wscale.y = windptr->iconsize.y;
  2219.     wscale.z = 1.0;
  2220.     ptk_scale3(&wscale, PTYPE_POSTCONCAT, mat);
  2221.     shift = ptk_point3(windptr->iconposition.x, windptr->iconposition.y,
  2222.                         0.0);
  2223.     ptk_shift3(&shift, PTYPE_POSTCONCAT, mat);
  2224.     pset_local_tran3(mat, PTYPE_REPLACE);
  2225.  
  2226.     plabel(ptk_stringtoint("label", "begin-icon"));
  2227.     buildicon();
  2228.     plabel(ptk_stringtoint("label", "begin-icon-pic"));
  2229.     do_structicon();
  2230.     plabel(ptk_stringtoint("label", "end-icon"));
  2231.  
  2232.     premove_names_set(&incl); 
  2233.     ptk_closestruct(); 
  2234.     ptk_unseteditmode();
  2235.   }
  2236. }  /* createwindow */
  2237.  
  2238. /*--------------------------------------------------------------------------*/
  2239.  
  2240. /*function:external*/
  2241. extern void ptk_createwindow(C(Pint) wsid, C(Pint) windid, C(Ppoint *) size,
  2242.                              C(Ppoint *) position, C(char *) titlestring)
  2243. PreANSI(Pint wsid)
  2244. PreANSI(Pint windid)
  2245. PreANSI(Ppoint *size)
  2246. PreANSI(Ppoint *position)
  2247. PreANSI(char *titlestring)
  2248. /* 
  2249. ** \parambegin
  2250. ** \param{Pint}{wsid}{workstation identifier}{IN}
  2251. ** \param{Pint}{windid}{window identifier}{IN}
  2252. ** \param{Ppoint *}{size}{window size}{IN}
  2253. ** \param{Ppoint *}{position}{window position}{IN}
  2254. ** \param{char *}{titlestring}{title string}{IN}
  2255. ** \paramend
  2256. ** \blurb{This function creates a window structure which may be used
  2257. ** for viewing PHIGS structures, PHIGS Toolkit topology diagrams and
  2258. ** PHIGS Toolkit structure content diagrams. A terminal window
  2259. ** type which contains only text. The window size and position are
  2260. ** given in the range [0, 1]. Each window has a virtual camera
  2261. ** which is useful for moving around a scene.
  2262. ** This function requires hashtables "structureid", "label", "name",
  2263. ** "viewindex".} 
  2264. */
  2265. {
  2266.   createwindow(wsid, windid, size, position, 0, 1, 1, 1, 1, titlestring);
  2267. }  /* ptk_createwindow */
  2268.  
  2269. /*--------------------------------------------------------------------------*/
  2270.  
  2271. /*function:external*/
  2272. extern void ptk_setwindowattrs(C(Pint) windid,
  2273.       C(Pint) titlefont, C(Pint) titlecolour, C(Pint) bannercolour,
  2274.       C(Pint) backgdcolour, C(Pint) edgecolour, 
  2275.       C(Pint) frametlcolour, C(Pint) framebrcolour)
  2276. PreANSI(Pint windid)
  2277. PreANSI(Pint titlefont)
  2278. PreANSI(Pint titlecolour)
  2279. PreANSI(Pint bannercolour)
  2280. PreANSI(Pint backgdcolour)
  2281. PreANSI(Pint edgecolour)
  2282. PreANSI(Pint frametlcolour)
  2283. PreANSI(Pint framebrcolour)
  2284. /* 
  2285. ** \parambegin
  2286. ** \param{Pint}{windid}{window identifier}{IN}
  2287. ** \param{Pint}{titlefont}{title string font}{IN}
  2288. ** \param{Pint}{titlecolour}{title string colour index}{IN}
  2289. ** \param{Pint}{bannercolour}{banner colour index}{IN}
  2290. ** \param{Pint}{backgdcolour}{background colour index of window}{IN}
  2291. ** \param{Pint}{edgecolour}{edge colour index of window}{IN}
  2292. ** \param{Pint}{frametlcolour}{top-left frame colour index}{IN}
  2293. ** \param{Pint}{framebrcolour}{bottom-right frame colour index}{IN}
  2294. ** \paramend
  2295. ** \blurb{This function sets the window text font and colour attribute
  2296. ** values. Each window has a banner region which contains the title
  2297. ** string of the window. The text font value applies to this string.} 
  2298. */
  2299. {   
  2300.   setwindow(windid);
  2301.   if (windptr != NULL)
  2302.   {  
  2303.     /* other window defaults */
  2304.     windptr->titlefont = titlefont;
  2305.     windptr->titlecolour = titlecolour;  
  2306.     windptr->bannercolour = bannercolour;
  2307.     windptr->backgdcolour = backgdcolour;
  2308.     windptr->edgecolour = edgecolour;
  2309.     windptr->frametlcolour = frametlcolour;
  2310.     windptr->framebrcolour = framebrcolour;
  2311.  
  2312.     ptk_seteditmode(PEDIT_INSERT);  
  2313.     ptk_openstruct(windptr->windowstid);
  2314.     pset_elem_ptr(0);  
  2315.     /* set window frame attributes */
  2316.     pdel_elems_labels(ptk_stringtoint("label", "begin-frame"), 
  2317.                   ptk_stringtoint("label", "end-frame"));  
  2318.     buildframe();
  2319.     ptk_closestruct();
  2320.  
  2321.     ptk_openstruct(windptr->iconstid);
  2322.     pset_elem_ptr(0);  
  2323.     /* set icon frame attributes */
  2324.     pdel_elems_labels(ptk_stringtoint("label", "begin-icon"), 
  2325.                   ptk_stringtoint("label", "begin-icon-pic"));  
  2326.     buildicon();
  2327.     ptk_closestruct();
  2328.     ptk_unseteditmode();
  2329.   }
  2330. }  /* ptk_setwindowattrs */
  2331.  
  2332. /*--------------------------------------------------------------------------*/
  2333.  
  2334. /*function:external*/
  2335. extern void ptk_posttowindow(C(Pint) windid, C(Pint) id)
  2336. PreANSI(Pint windid) 
  2337. PreANSI(Pint id) 
  2338. /*
  2339. ** \parambegin
  2340. ** \param{Pint}{windid}{window identifier}{IN}
  2341. ** \param{Pint}{id}{item identifier}{IN}
  2342. ** \paramend
  2343. ** \blurb{This function posts an item to a window depending on the 
  2344. ** window type. In the case
  2345. ** of STRUCT and CONTENT windows, {\tt id} is a structure identifier.
  2346. ** For TOPOLOGY windows, {\tt id} is a topology identifier. If the window is
  2347. ** a TERMINAL window this function is ignored.}
  2348. */
  2349. {
  2350.   Pint stid, err, elptr, lstnum, fid;
  2351.   Pelem_type eltype;
  2352.   Psearch_status stat;
  2353.   ptkboolean found;
  2354.  
  2355.   setwindow(windid);
  2356.   if (windptr != NULL)
  2357.   {
  2358.     if (windptr->windowtype != PTKETERMINALWINDOW)
  2359.     {
  2360.       if (windptr->windowtype == PTKETOPOLOGYWINDOW)
  2361.         ptk_inqtopologystructid(id, &stid, &err);
  2362.       else
  2363.         stid = id;
  2364.       /* add to window structure */
  2365.       ptk_openstruct(windptr->windowstid);
  2366.       ptk_seteditmode(PEDIT_INSERT);
  2367.       pset_elem_ptr(0);
  2368.       pset_elem_ptr_label(ptk_stringtoint("label", "begin-window"));
  2369.   
  2370.       /* check if execute is already there */
  2371.       eltype = PELEM_EXEC_STRUCT;
  2372.       found = FALSE;
  2373.       do
  2374.       {
  2375.         ptk_findelemtype(&eltype, 1, PDIR_FORWARD, &stat, &elptr, &lstnum);
  2376.         if (stat == PSEARCH_STATUS_SUCCESS)
  2377.     {
  2378.           ptk_getexecuteid(windptr->windowstid, elptr, &fid);
  2379.           if (fid == stid)
  2380.             found = TRUE;
  2381.           pset_elem_ptr(elptr + 1);
  2382.         }
  2383.       } while ((!found) && (stat == PSEARCH_STATUS_SUCCESS)); 
  2384.       if (!found)
  2385.       {
  2386.         pset_elem_ptr(0);
  2387.         pset_elem_ptr_label(ptk_stringtoint("label", "begin-window"));
  2388.         pexec_struct(stid);
  2389.       }
  2390.       ptk_unseteditmode();
  2391.       ptk_closestruct();
  2392.       if (windptr->windowtype == PTKECONTENTWINDOW)
  2393.       {
  2394.         ptk_inqstructcontentrange(stid, &windptr->range1, &windptr->range2,
  2395.                                   &err);
  2396.         windptr->viewrange1 = 0;
  2397.         windptr->viewrange2 = windptr->range2;
  2398.       }
  2399.     }
  2400.   }
  2401. }  /* ptk_posttowindow */
  2402.  
  2403. /*--------------------------------------------------------------------------*/
  2404.  
  2405. /*function:external*/
  2406. extern void ptk_frontwindow(C(Pint) windid)
  2407. PreANSI(Pint windid)
  2408. /*
  2409. ** \parambegin
  2410. ** \param{Pint}{windid}{window identifier}{IN}
  2411. ** \paramend 
  2412. ** \blurb{This function sets the post priority of the window structure
  2413. ** so that it is displayed on top of all other posted windows but
  2414. ** has a lower prioity than the current back menu.}
  2415. */
  2416. {
  2417.   Pint ind, err, frontmenu, backmenu, backmenustid;
  2418.   ptkboolean menus;
  2419.  
  2420.   setwindow(windid);
  2421.   if (windptr != NULL)
  2422.   {
  2423.     findwsid(windptr->wsid, &ind);
  2424.     menus = ptk_inqfrontbackmenuid(windptr->wsid, &frontmenu, &backmenu, 
  2425.                                    &err);
  2426.     if (menus)
  2427.     {
  2428.       ptk_inqmenustructid(backmenu, &backmenustid, &err);
  2429.       ptk_postrelative(windptr->wsid, windptr->currentstid, PPRI_LOWER,
  2430.                          backmenustid, &err);
  2431.     }
  2432.     else
  2433.     if (!wswindows[ind].postedwindows)
  2434.       ppost_struct(windptr->wsid, windptr->windowstid, 0.0);
  2435.     else
  2436.       ptk_postrelative(windptr->wsid, windptr->currentstid, PPRI_HIGHER,
  2437.                        wswindows[ind].frontptr->currentstid, &err);
  2438.     if (!wswindows[ind].postedwindows)
  2439.     {
  2440.       wswindows[ind].frontptr = wswindows[ind].backptr = windptr;
  2441.       wswindows[ind].postedwindows = TRUE;
  2442.     }
  2443.     else
  2444.     {
  2445.       wswindows[ind].frontptr = windptr;
  2446.       if (windptr->currentstid == wswindows[ind].backptr->currentstid)
  2447.         findback(windptr->wsid, &wswindows[ind]);
  2448.     }
  2449.     windptr->posted = TRUE;
  2450.   }
  2451. }  /* ptk_frontwindow */
  2452.  
  2453. /*--------------------------------------------------------------------------*/
  2454.  
  2455. /*function:external*/
  2456. extern void ptk_backwindow(C(Pint) windid)
  2457. PreANSI(Pint windid)
  2458. /*
  2459. ** \parambegin
  2460. ** \param{Pint}{windid}{window identifier}{IN}
  2461. ** \paramend 
  2462. ** \blurb{This function sets the post priority of a window structure
  2463. ** so that it is displayed behind all the other posted windows and menus.}
  2464. */
  2465. {
  2466.   Pint ind, err, frontmenu, backmenu, backmenustid;
  2467.   ptkboolean menus;
  2468.  
  2469.   setwindow(windid);
  2470.   if (windptr != NULL)
  2471.   {
  2472.     findwsid(windptr->wsid, &ind);
  2473.     menus = ptk_inqfrontbackmenuid(windptr->wsid, &frontmenu, &backmenu,
  2474.                                    &err);
  2475.     if (!wswindows[ind].postedwindows)
  2476.     {
  2477.       if (menus)
  2478.       {
  2479.         ptk_inqmenustructid(backmenu, &backmenustid, &err);
  2480.         ptk_postrelative(windptr->wsid, windptr->currentstid, PPRI_LOWER,
  2481.                          backmenustid, &err);
  2482.       }
  2483.       else
  2484.         ppost_struct(windptr->wsid, windptr->currentstid, 0.0);
  2485.       wswindows[ind].frontptr = wswindows[ind].backptr = windptr;
  2486.       wswindows[ind].postedwindows = TRUE;
  2487.     }
  2488.     else
  2489.     {
  2490.       ptk_postrelative(windptr->wsid, windptr->currentstid, PPRI_LOWER,
  2491.                        wswindows[ind].backptr->currentstid, &err);
  2492.       wswindows[ind].backptr = windptr;
  2493.       if (windptr == wswindows[ind].frontptr)
  2494.         findfront(windptr->wsid, &wswindows[ind]);
  2495.     }
  2496.     windptr->posted = TRUE;
  2497.   }
  2498. }  /* ptk_backwindow */
  2499.  
  2500. /*--------------------------------------------------------------------------*/
  2501.  
  2502. /*function:external*/
  2503. extern void ptk_unpostfromwindow(C(Pint) windid, C(Pint) id)
  2504. PreANSI(Pint windid) 
  2505. PreANSI(Pint id) 
  2506. /*
  2507. ** \parambegin
  2508. ** \param{Pint}{windid}{window identifier}{IN}
  2509. ** \param{Pint}{id}{item identifier}{IN}
  2510. ** \paramend
  2511. ** \blurb{This function unposts an item from a window depending on the
  2512. ** window type. In the case
  2513. ** of STRUCT and CONTENT windows, id is a structure identifier.
  2514. ** For TOPOLOGY windows, id is a topology identifier. If the window is
  2515. ** a TERMINAL window this function is ignored.}
  2516. */
  2517. {
  2518.   Pint stid, elptr, lstnum, err, fid;
  2519.   Pelem_type eltype;
  2520.   Psearch_status stat;
  2521.   ptkboolean found;
  2522.  
  2523.   setwindow(windid);
  2524.   if (windptr != NULL)
  2525.   {
  2526.     if (windptr->windowtype != PTKETERMINALWINDOW)
  2527.     {
  2528.       if (windptr->windowtype == PTKETOPOLOGYWINDOW)
  2529.         ptk_inqtopologystructid(id, &stid, &err);
  2530.       else
  2531.         stid = id;
  2532.       /* add to window structure */
  2533.       ptk_openstruct(windptr->windowstid);
  2534.       ptk_seteditmode(PEDIT_INSERT);
  2535.       pset_elem_ptr(0);
  2536.       pset_elem_ptr_label(ptk_stringtoint("label", "begin-window"));
  2537.   
  2538.       /* check if execute is already there */
  2539.       eltype = PELEM_EXEC_STRUCT;
  2540.       found = FALSE;
  2541.       do
  2542.       {
  2543.         ptk_findelemtype(&eltype, 1, PDIR_FORWARD, &stat, &elptr, &lstnum);
  2544.         if (stat == PSEARCH_STATUS_SUCCESS)
  2545.     {
  2546.           ptk_getexecuteid(windptr->windowstid, elptr, &fid);
  2547.           if (fid == stid)
  2548.             found = TRUE;
  2549.           pset_elem_ptr(elptr + 1);
  2550.         }
  2551.       } while ((!found) && (stat == PSEARCH_STATUS_SUCCESS));
  2552.       if (found)
  2553.       {
  2554.         pset_elem_ptr(elptr);
  2555.         pdel_elem();
  2556.       }
  2557.       ptk_unseteditmode();
  2558.       ptk_closestruct();
  2559.     }
  2560.   }
  2561. }  /* ptk_unpostfromwindow */
  2562.  
  2563. /*--------------------------------------------------------------------------*/
  2564.  
  2565. /*function:external*/
  2566. extern void ptk_unpostallfromwindow(C(Pint) windid)
  2567. PreANSI(Pint windid)
  2568. /*
  2569. ** \parambegin
  2570. ** \param{Pint}{windid}{window identifier}{IN}
  2571. ** \paramend 
  2572. ** \blurb{This function unposts all items posted to window {\tt windid}.
  2573. ** If the window is a TERMINAL window this function is ignored.}
  2574. */
  2575. {
  2576.   Pint label1, label2;
  2577.  
  2578.   setwindow(windid);
  2579.   if (windptr != NULL)
  2580.   {
  2581.     if (windptr->windowtype != PTKETERMINALWINDOW)
  2582.     {
  2583.       ptk_openstruct(windptr->windowstid);
  2584.       /* Implementation dependent code
  2585.       ** because of problem with delelemslabels in SunPHIGS
  2586.       */
  2587. #ifdef SUN
  2588.       pset_elem_ptr(0);
  2589.       ptk_findlabel(ptk_stringtoint("label", "begin-window"), &label1);
  2590.       pset_elem_ptr(0);
  2591.       ptk_findlabel(ptk_stringtoint("label", "end-window"), &label2);
  2592.       if ((label2 - label1) > 1)
  2593.       {
  2594.         if ((label2 - label1) == 2)
  2595.     {
  2596.           pset_elem_ptr(0);
  2597.           pset_elem_ptr(label1);
  2598.           poffset_elem_ptr(1);
  2599.           pdel_elem();
  2600.         }
  2601.         else
  2602.           pdel_elem_range(label1 + 1, label2 - 1);
  2603.       }
  2604. #endif
  2605. #ifndef SUN
  2606.       /* do for HP and PEXSI */
  2607.       pset_elem_ptr(0);
  2608.       pdel_elems_labels(ptk_stringtoint("label", "begin-window"),
  2609.             ptk_stringtoint("label", "end-window"));
  2610. #endif
  2611.       ptk_closestruct();
  2612.     }
  2613.   }
  2614. }  /* ptk_unpostallfromwindow */
  2615.  
  2616. /*--------------------------------------------------------------------------*/
  2617.  
  2618. /*function:external*/
  2619. extern void ptk_postwindow(C(Pint) windid)
  2620. PreANSI(Pint windid) 
  2621. /*
  2622. ** \parambegin
  2623. ** \param{Pint}{windid}{window identifier}{IN}
  2624. ** \paramend
  2625. ** \blurb{This function posts a window structure to the workstation
  2626. ** specified when the window was initially created. Windows are bound
  2627. ** to workstation because they each use one view table entry to
  2628. ** define the window view. The priority of the window structure is
  2629. ** controlled by the PHIGS Toolkit window system to provide an ordered
  2630. ** stacking mechanism for windows.}
  2631. */
  2632. {
  2633.   ptk_frontwindow(windid);
  2634. }  /* ptk_postwindow */
  2635.  
  2636. /*--------------------------------------------------------------------------*/
  2637.  
  2638. /*function:external*/
  2639. extern void ptk_unpostwindow(C(Pint) windid)
  2640. PreANSI(Pint windid) 
  2641. /*
  2642. ** \parambegin
  2643. ** \param{Pint}{windid}{window identifier}{IN}
  2644. ** \paramend
  2645. ** \blurb{This function unposts a window from the workstation it is
  2646. ** bound to.}
  2647. */
  2648. {
  2649.   Pint ind;
  2650.  
  2651.   setwindow(windid);
  2652.   if (windptr != NULL)
  2653.   {
  2654.     punpost_struct(windptr->wsid, windptr->currentstid);
  2655.     findwsid(windptr->wsid, &ind);
  2656.     if (windptr == wswindows[ind].backptr)
  2657.       findback(windptr->wsid, &wswindows[ind]);
  2658.     if (windptr == wswindows[ind].frontptr)
  2659.       findfront(windptr->wsid, &wswindows[ind]);
  2660.     windptr->posted = FALSE;
  2661.   }
  2662. }  /* ptk_unpostwindow */
  2663.  
  2664. /*--------------------------------------------------------------------------*/
  2665.  
  2666. /*function:external*/
  2667. extern ptkboolean ptk_delwindow(C(Pint) windid)
  2668. PreANSI(Pint windid) 
  2669. /*
  2670. ** \parambegin
  2671. ** \param{Pint}{windid}{window identifier}{IN}
  2672. ** \paramend
  2673. ** \blurb{This function deletes a window from the PHIGS Toolkit window
  2674. ** store.}
  2675. */
  2676. {
  2677.   ptkswindow *ptr, *junk;
  2678.   char stname[20];
  2679.  
  2680.   ptk_unpostwindow(windid);
  2681.   ptr = firstwind;
  2682.   if (ptr->windowid == windid)
  2683.   {
  2684.     firstwind = firstwind->next;
  2685.     if (lastwind->windowid == windid)
  2686.       lastwind = firstwind;
  2687.     pdel_struct(ptr->windowstid);
  2688.     pdel_struct(ptr->iconstid);
  2689.     if (ptr->windowtype == PTKETERMINALWINDOW)
  2690.     {
  2691.       pdel_struct(ptr->term.textstid);
  2692.       sprintf(stname, "ptk$term%d", windid);
  2693.       ptk_delstring("structureid", stname);
  2694.     }
  2695.     free(ptr);
  2696.   }
  2697.   else
  2698.   {
  2699.     while (ptr->next->windowid != windid)
  2700.     {
  2701.       ptr = ptr->next;
  2702.       if (ptr->next == NULL)
  2703.         return FALSE;
  2704.     }
  2705.     junk = ptr->next;
  2706.     ptr->next = junk->next;
  2707.     pdel_struct(junk->windowstid);
  2708.     pdel_struct(junk->iconstid);
  2709.     if (ptr->windowtype == PTKETERMINALWINDOW)
  2710.     {
  2711.       pdel_struct(junk->term.textstid);
  2712.       sprintf(stname, "ptk$term%d", windid);
  2713.       ptk_delstring("structureid", stname);
  2714.     }
  2715.     free(junk);
  2716.     if (ptr->next == NULL)
  2717.       lastwind = ptr;
  2718.   }
  2719.  
  2720.   /* delete strings */
  2721.   sprintf(stname, "ptk$window%d", windid);
  2722.   ptk_delstring("structureid", stname);
  2723.   sprintf(stname, "ptk$icon%d", windid);
  2724.   ptk_delstring("structureid", stname);
  2725.   sprintf(stname, "view$window%d", windid);
  2726.   ptk_delstring("viewindex", stname);
  2727.   sprintf(stname, "name$window%d", windid);
  2728.   ptk_delstring("name", stname);
  2729.   windowcount--;
  2730.   return TRUE;
  2731. }  /* ptk_delwindow */
  2732.  
  2733. /*--------------------------------------------------------------------------*/
  2734.  
  2735. /*function:external*/
  2736. extern void ptk_openwindow(C(Pint) windid)
  2737. PreANSI(Pint windid)
  2738. /*
  2739. ** \parambegin
  2740. ** \param{Pint}{windid}{window identifier}{IN}
  2741. ** \paramend 
  2742. ** \blurb{This function posts the window structure and unposts the icon
  2743. ** structure from the window's workstation.}
  2744. */
  2745. {
  2746.   Pfloat priority;
  2747.   Pint err;
  2748.  
  2749.   setwindow(windid);
  2750.   if (windptr != NULL)
  2751.   {
  2752.     if (windptr->windowstate == PTKEWINDOWCLOSED)
  2753.     {
  2754.       ptk_inqpostpriority(windptr->wsid, windptr->iconstid, &priority, &err);
  2755.       punpost_struct(windptr->wsid, windptr->iconstid);
  2756.       ppost_struct(windptr->wsid, windptr->windowstid, priority);
  2757.       windptr->windowstate = PTKEWINDOWOPEN;
  2758.       windptr->currentstid = windptr->windowstid;
  2759.       if (windptr->viewstate == PVISUAL_ST_DEFER)
  2760.       {
  2761.         updatewindowview();
  2762.         windptr->viewstate = PVISUAL_ST_CORRECT;
  2763.       }
  2764.     }
  2765.   }
  2766. }  /* ptk_openwindow */
  2767.  
  2768. /*--------------------------------------------------------------------------*/
  2769.  
  2770. /*function:external*/
  2771. extern void ptk_closewindow(C(Pint) windid)
  2772. PreANSI(Pint windid)
  2773. /*
  2774. ** \parambegin
  2775. ** \param{Pint}{windid}{window identifier}{IN}
  2776. ** \paramend 
  2777. ** \blurb{This function posts the icon structure and unposts the window
  2778. ** structure from the window's workstation.}
  2779. */
  2780. {
  2781.   Pfloat priority;
  2782.   Pint err;
  2783.  
  2784.   setwindow(windid);
  2785.   if (windptr != NULL)
  2786.   {
  2787.     if (windptr->windowstate == PTKEWINDOWOPEN)
  2788.     {
  2789.       ptk_inqpostpriority(windptr->wsid, windptr->windowstid, &priority, 
  2790.                           &err);
  2791.       punpost_struct(windptr->wsid, windptr->windowstid);
  2792.       ppost_struct(windptr->wsid, windptr->iconstid, priority);
  2793.       windptr->windowstate = PTKEWINDOWCLOSED;
  2794.       windptr->currentstid = windptr->iconstid;
  2795.     }
  2796.   }
  2797. }  /* ptk_closewindow */
  2798.  
  2799. /*--------------------------------------------------------------------------*/
  2800.  
  2801. /*function:external*/
  2802. extern void ptk_setwindowposition(C(Pint) windid, C(Ppoint *) position)
  2803. PreANSI(Pint windid)
  2804. PreANSI(Ppoint *position)
  2805. /*
  2806. ** \parambegin
  2807. ** \param{Pint}{windid}{window identifier}{IN}
  2808. ** \param{Ppoint *}{position}{window position}{IN}
  2809. ** \paramend 
  2810. ** \blurb{This function sets the position of the centre of the window.
  2811. ** The position is given in the range [0, 1]. If the position results
  2812. ** in part of the window being clipped then the position is adjusted
  2813. ** so that the whole window is visible.}
  2814. */
  2815.   setwindow(windid);
  2816.   if (windptr != NULL)
  2817.   {
  2818.     windptr->windowposition = *position;
  2819.     setvalidwindowpos();
  2820.     updateframe();
  2821.     if (windptr->windowtype == PTKESTRUCTWINDOW)
  2822.       adjustlimits(&windptr->viewvolume); 
  2823.     if (windptr->windowtype == PTKETERMINALWINDOW)
  2824.       windptr->proj_vp = windptr->cliplimit = windptr->viewlims;
  2825.     if (windptr->windowtype == PTKECONTENTWINDOW)
  2826.       ptk_setcontentviewrange(windid, windptr->viewrange1, 
  2827.                               windptr->viewrange2);
  2828.     else
  2829.       updatewindowview();
  2830.   }
  2831. }  /* ptk_setwindowposition */
  2832.  
  2833. /*--------------------------------------------------------------------------*/
  2834.  
  2835. /*function:external*/
  2836. extern void ptk_setwindowsize(C(Pint) windid, C(Ppoint *) size)
  2837. PreANSI(Pint windid)
  2838. PreANSI(Ppoint *size)
  2839. /*
  2840. ** \parambegin
  2841. ** \param{Pint}{windid}{window identifier}{IN}
  2842. ** \param{Ppoint *}{size}{window size}{IN}
  2843. ** \paramend 
  2844. ** \blurb{This function sets the size of the window using the x value
  2845. ** as the width and the y value as the height. The values are given
  2846. ** in the range [0, 1]. If the size results in part of the window
  2847. ** being clipped then the window size is adjusted to give as large a
  2848. ** window as possible.}
  2849. */
  2850. {
  2851.   Pfloat height, extraspace, textspace, oldlinesize;
  2852.   Pfloat newlinesize, newlines;
  2853.   Ppoint oldsize;
  2854.  
  2855.   setwindow(windid);
  2856.   if (windptr != NULL)
  2857.   {
  2858.     oldsize = windptr->windowsize;
  2859.     windptr->windowsize = *size;
  2860.     setvalidwindowsize();
  2861.     switch (windptr->windowtype)
  2862.     {
  2863.       case PTKESTRUCTWINDOW:
  2864.         updateframe();
  2865.         adjustlimits(&windptr->viewvolume);
  2866.         updatewindowview();
  2867.         break;
  2868.  
  2869.       case PTKETERMINALWINDOW:
  2870.         windptr->term.realcols *= (windptr->windowsize.x / oldsize.x); 
  2871.         windptr->term.columns = windptr->term.curr_colm = 
  2872.                                   (Pint)windptr->term.realcols;
  2873.         height = windptr->windowsize.y / oldsize.y;
  2874.         oldlinesize = oldsize.y/(Pfloat)windptr->term.lines;
  2875.         windptr->term.reallines *= height;
  2876.         newlines = (Pfloat)floor(windptr->term.reallines);
  2877.         extraspace = windptr->windowsize.y - (oldsize.y * 
  2878.                                 (newlines / (Pfloat)windptr->term.lines));
  2879.         windptr->term.lines = (Pint)windptr->term.reallines;
  2880.         windptr->term.increment += extraspace/newlines;
  2881.         newlinesize = size->y/(Pfloat)windptr->term.lines; 
  2882.         textspace = (Pfloat)windptr->term.curr_line * oldlinesize;
  2883.         windptr->term.curr_line = (Pint)((Pfloat)textspace / newlinesize) + 1;
  2884.         updateframe();
  2885.         initialiseterminal();
  2886.         break;
  2887.  
  2888.       case PTKECONTENTWINDOW:
  2889.         updateframe();
  2890.         ptk_setcontentviewrange(windid, windptr->viewrange1, 
  2891.                                 windptr->viewrange2);
  2892.         break;
  2893.  
  2894.       case PTKETOPOLOGYWINDOW:
  2895.         updateframe();
  2896.         ptk_settopologyviewarea(windid, &windptr->topviewarea);
  2897.         break;
  2898.     }
  2899.   }
  2900. }  /* ptk_setwindowsize */
  2901.  
  2902. /*--------------------------------------------------------------------------*/
  2903.  
  2904. /*function:external*/
  2905. extern void ptk_setwindowtraninputpri(C(Pint) windid, C(Pint) refwindid, 
  2906.                                       C(Prel_pri) priority)
  2907. PreANSI(Pint windid)
  2908. PreANSI(Pint refwindid)
  2909. PreANSI(Prel_pri priority)
  2910. /*
  2911. ** \parambegin
  2912. ** \param{Pint}{windid}{window identifier}{IN}
  2913. ** \param{Pint}{refwindid}{reference window identifier}{IN}
  2914. ** \param{Prel\_pri}{priority}{relative priority}{IN}
  2915. ** \paramend 
  2916. ** \blurb{This function sets the transformation input priority of the 
  2917. ** window's view representation relative to another window.
  2918. ** The relative priority is also set relative to view index 0.}
  2919. */
  2920. {
  2921.   Pint refindex;
  2922.   ptkswindow *ptrwindow;
  2923.  
  2924.   setwindow(windid);
  2925.   if (windptr != NULL)
  2926.   {
  2927.     if (iswindow(refwindid, &ptrwindow))
  2928.     {
  2929.       refindex = ptrwindow->windowviewind;
  2930.       pset_view_tran_in_pri(windptr->wsid, windptr->windowviewind, refindex,
  2931.                            priority);
  2932.     }
  2933.     pset_view_tran_in_pri(windptr->wsid, windptr->windowviewind, 0,
  2934.                          priority);
  2935.   }
  2936. }  /* ptk_setwindowtraninputpri */
  2937.  
  2938. /*--------------------------------------------------------------------------*/
  2939.  
  2940. /*function:external*/
  2941. extern void ptk_setframesize(C(Pint) windid, C(Ppoint *) size)
  2942. PreANSI(Pint windid)
  2943. PreANSI(Ppoint *size)
  2944. /*
  2945. ** \parambegin
  2946. ** \param{Pint}{windid}{window identifier}{IN}
  2947. ** \param{Ppoint *}{size}{frame size}{IN}
  2948. ** \paramend 
  2949. ** \blurb{This function sets the thickness of the window frame. The
  2950. ** x and y dimensions are given in the range [0, 1].}
  2951. */
  2952. {
  2953.   setwindow(windid);
  2954.   if (windptr != NULL)
  2955.   {
  2956.     if ((size->x > 0.0) && (size->y > 0.0))
  2957.     {  
  2958.       windptr->framesize = *size;
  2959.       updateframe();
  2960.     }
  2961.   }
  2962. }  /* ptk_setframesize */
  2963.  
  2964. /*--------------------------------------------------------------------------*/
  2965.  
  2966. /*function:external*/
  2967. extern ptkboolean ptk_stringscanwindows(C(Pint) wsid, C(char *) str, 
  2968.                                 C(Pint *) windowid)
  2969. PreANSI(Pint wsid)
  2970. PreANSI(char *str)
  2971. PreANSI(Pint *windowid)
  2972. /*
  2973. ** \parambegin
  2974. ** \param{Pint}{wsid}{workstation identifier}{IN}
  2975. ** \param{char *}{str}{string}{IN}
  2976. ** \param{Pint *}{windowid}{window identifier}{OUT}
  2977. ** \paramend
  2978. ** \blurb{This function compares the character string {\tt str} with
  2979. ** title string of all the windows posted to workstation {\tt wsid}.
  2980. ** The string comparison is case sensitive and begins with the
  2981. ** front window and works back to the lowest priority window.
  2982. ** The function returns TRUE if a match is found, otherwise FALSE.}
  2983. */
  2984. {
  2985.   ptkboolean windowfound;
  2986.   Pint_list *windows;
  2987.   ptkswindow *ptrwindow;
  2988.   Pint numstructs, i, err;
  2989.   Pposted_struct_list structlist;
  2990.   Pfilter *invisfilt;
  2991.   Pstore store;
  2992.  
  2993.   windowfound = FALSE;
  2994.   structlist.postings = NULL;
  2995.   pinq_posted_structs(wsid, 0, 0, &err, &structlist, &numstructs);
  2996.   structlist.postings = (Pposted_struct *)calloc(numstructs, 
  2997.                                               sizeof(Pposted_struct));
  2998.   pinq_posted_structs(wsid, numstructs, 0, &err, &structlist, &numstructs);
  2999.  
  3000.   /* inquire invisibility filter */
  3001.   pcreate_store(&err, &store);
  3002.   pinq_invis_filter(wsid, store, &err, &invisfilt);
  3003.  
  3004.   /* This bit is a bit dodgy because it relies on structlist being ordered
  3005.   ** by PHIGS into highest priority last. This is not standard PHIGS,
  3006.   ** so if version is not sorted do a sort.
  3007.   */
  3008.   i = numstructs - 1;
  3009.   while ((i >= 0) && (!windowfound)) 
  3010.   {
  3011.     if (iswindow(structlist.postings[i].id, &ptrwindow))
  3012.     {
  3013.       /* check invisibility filter */
  3014.       if (!((inintlst(ptrwindow->windowname, &invisfilt->incl_set) != -1) && 
  3015.           (inintlst(ptrwindow->windowname, &invisfilt->excl_set) == -1)))
  3016.       {
  3017.         if (find_string(ptrwindow->currentstid, str))
  3018.         {
  3019.           windowfound = TRUE;
  3020.           *windowid = ptrwindow->windowid;
  3021.         }
  3022.       }
  3023.     }
  3024.     i--;
  3025.   }
  3026.   ptk_delstore(store);
  3027.   free(structlist.postings);
  3028.   return windowfound;
  3029. }  /* ptk_stringscanwindows */
  3030.  
  3031. /*--------------------------------------------------------------------------*/
  3032.  
  3033. /*function:external*/
  3034. extern ptkboolean ptk_pickscanwindows(C(Ppick_path *) pickpath, 
  3035.   C(Ppath_order) pathorder, C(Pint *) windowid, C(ptkewindowarea *) windowarea)
  3036. PreANSI(Ppick_path *pickpath)
  3037. PreANSI(Ppath_order pathorder)
  3038. PreANSI(Pint *windowid)
  3039. PreANSI(ptkewindowarea *windowarea)
  3040. /*
  3041. ** \parambegin
  3042. ** \param{Ppick\_path *}{pickpath}{path through structure network}{IN}
  3043. ** \param{Ppath\_order}{pathorder}{order of path through network}{IN}
  3044. ** \param{Pint *}{windowid}{window identifier}{OUT}
  3045. ** \paramend
  3046. ** \blurb{This function tests the pick path to inquire if a window 
  3047. ** structure was picked. The window area picked may be one of
  3048. ** BANNER, VIEW, FRAME or ICON. The function
  3049. ** returns TRUE if a window was picked, otherwise FALSE.}
  3050. */
  3051. {
  3052.   Pint windowstid;
  3053.  
  3054.   if (pathorder == PORDER_TOP_FIRST)
  3055.   {
  3056.     *windowarea = pickpath->path_list[pickpath->depth - 1].pick_id;
  3057.     windowstid = pickpath->path_list[0].struct_id;
  3058.     return (getwindowid(windowstid, windowid));
  3059.   }
  3060.   else
  3061.   {
  3062.     *windowarea = pickpath->path_list[0].pick_id;
  3063.     windowstid = pickpath->path_list[pickpath->depth - 1].struct_id;
  3064.     return (getwindowid(windowstid, windowid));
  3065.   }
  3066. }  /* ptk_pickscanwindows */
  3067.  
  3068. /*--------------------------------------------------------------------------*/
  3069.  
  3070. /*function:external*/
  3071. extern ptkboolean ptk_locscanwindows(C(Pint) wsid, C(Ppoint *) point, 
  3072.         C(Pint *) windowid, C(ptkewindowarea *) windowarea, C(Ppoint *) value)
  3073. PreANSI(Pint wsid)
  3074. PreANSI(Ppoint *point)
  3075. PreANSI(Pint *windowid)
  3076. PreANSI(ptkewindowarea *windowarea)
  3077. PreANSI(Ppoint *value)
  3078. /*
  3079. ** \parambegin
  3080. ** \param{Pint}{wsid}{workstation identifier}{IN}
  3081. ** \param{Ppoint *}{point}{input point}{IN}
  3082. ** \param{Pint *}{windowid}{window identifier}{OUT}
  3083. ** \param{ptkewindowarea *}{windowarea}{window area}{OUT}
  3084. ** \param{Ppoint *}{value}{position of point within window area}{OUT}
  3085. ** \paramend
  3086. ** \blurb{This function uses the INCREMENTAL SPATIAL SEARCH function 
  3087. ** of PHIGS to test if {\tt point} lies within a window
  3088. ** posted to workstation {\tt wsid}. The window area (one of
  3089. ** BANNER, VIEW, FRAME or ICON) and the position of {\tt point} relative
  3090. ** to the bottom-left corner of the bounding box of the window area are
  3091. ** returned in {\tt windowarea} and {\tt value}.
  3092. ** The function returns TRUE if {\tt point} lies within a window,
  3093. ** otherwise FALSE.}
  3094. */
  3095. {
  3096.   ptkboolean windowfound;
  3097.   ptkswindow *ptrwindow;
  3098.   Plimit3 windowbox, area;
  3099.   Pint numstructs, i, err;
  3100.   Pposted_struct_list structlist;
  3101.   Pint lstnum, stopelem;
  3102.   Pelem_type eltype;
  3103.   Psearch_status stat;
  3104.   Pfloat div;
  3105.   Pfilter *invisfilt;
  3106.   Pstore store;
  3107.  
  3108.   ptk_stacktsl();
  3109.   ptk_stackbbox();
  3110.   eltype = PELEM_VIEW_IND;
  3111.   windowfound = FALSE;
  3112.   structlist.postings = NULL;
  3113.   pinq_posted_structs(wsid, 0, 0, &err, &structlist, &numstructs);
  3114.   structlist.postings = (Pposted_struct *)calloc(numstructs, 
  3115.                                               sizeof(Pposted_struct));
  3116.   pinq_posted_structs(wsid, numstructs, 0, &err, &structlist, &numstructs);
  3117.  
  3118.   /* inquire invisibility filter */
  3119.   pcreate_store(&err, &store);
  3120.   pinq_invis_filter(wsid, store, &err, &invisfilt);
  3121.  
  3122.   /* This bit is a bit dodgy because it relies on structlist being ordered
  3123.   ** by PHIGS into highest priority last. This is not standard PHIGS,
  3124.   ** so if version is not sorted do a sort.
  3125.   ** HP orders with highest priority first.
  3126.   */
  3127. #ifndef HP
  3128.   /* do for SUN and PEXSI */
  3129.   i = numstructs - 1;
  3130.   while ((i >= 0) && (!windowfound)) 
  3131. #endif
  3132. #ifdef HP
  3133.   i = 0;
  3134.   while ((i < numstructs) && (!windowfound)) 
  3135. #endif
  3136.   {
  3137.     if (iswindow(structlist.postings[i].id, &ptrwindow))
  3138.     {
  3139.       /* check invisibility filter */
  3140.       if (!((inintlst(ptrwindow->windowname, &invisfilt->incl_set) != -1) && 
  3141.           (inintlst(ptrwindow->windowname, &invisfilt->excl_set) == -1)))
  3142.       {
  3143.         if (ptrwindow->windowstate == PTKEWINDOWOPEN)
  3144.     {
  3145.           ptk_openstruct(ptrwindow->currentstid);
  3146.           pset_elem_ptr(0);
  3147.           ptk_findelemtype(&eltype, 1, PDIR_FORWARD, &stat, &stopelem, &lstnum);
  3148.           ptk_closestruct();
  3149.           ptk_inittsl();
  3150.           ptk_tsltraverserange(ptrwindow->currentstid, 1, 
  3151.                                ptrwindow->currentstid, stopelem, TRUE);
  3152.           ptk_inqboundingbox(&windowbox);
  3153.         }
  3154.         else
  3155.           ptk_boundingbox(ptrwindow->currentstid, &windowbox, TRUE);
  3156.         if (ptinlimit3(point, &windowbox))
  3157.         {
  3158.           windowfound = TRUE;
  3159.           *windowid = ptrwindow->windowid;
  3160.           *value = ptk_point(0.0, 0.0);
  3161.         }
  3162.       }
  3163.     }
  3164.     if (!windowfound)
  3165. #ifndef HP
  3166.       /* do for SUN and PEXSI */
  3167.       i--;
  3168. #endif
  3169. #ifdef HP
  3170.       i++;
  3171. #endif
  3172.   }
  3173.   if (windowfound)
  3174.   {
  3175.     if (ptrwindow->windowstate == PTKEWINDOWCLOSED)
  3176.     {
  3177.       *windowarea = PTKEWINDOWICON;
  3178.       ptk_boundingbox(ptrwindow->iconstid, &area, TRUE);
  3179.     }
  3180.     else
  3181.     {
  3182.       area = ptk_limit3(ptrwindow->windowposition.x - 
  3183.                     (ptrwindow->windowsize.x / 2.0),
  3184.                     ptrwindow->windowposition.x + 
  3185.                     (ptrwindow->windowsize.x / 2.0),
  3186.                     ptrwindow->windowposition.y - 
  3187.                     (ptrwindow->windowsize.y / 2.0),
  3188.                     ptrwindow->windowposition.y + 
  3189.                     (ptrwindow->windowsize.y / 2.0), 0.0, 0.0);
  3190.       if (ptinlimit3(point, &area))
  3191.         *windowarea = PTKEWINDOWVIEW;
  3192.       else
  3193.       {
  3194.         area.y_min = area.y_max;
  3195.         area.y_max += ptrwindow->bannerheight;
  3196.         if (ptinlimit3(point, &area))
  3197.           *windowarea = PTKEWINDOWBANNER;
  3198.         else
  3199.     {
  3200.           *windowarea = PTKEWINDOWFRAME;
  3201. /*#ifdef HP
  3202.           area = windowbox;
  3203. #endif
  3204. #ifdef SUN
  3205. */
  3206.           ptk_openstruct(ptrwindow->currentstid);
  3207.           pset_elem_ptr(0);
  3208.           ptk_findelemtype(&eltype, 1, PDIR_FORWARD, &stat, &stopelem, &lstnum);
  3209.           ptk_closestruct();
  3210.           ptk_inittsl();
  3211.           ptk_tsltraverserange(ptrwindow->currentstid, 1, 
  3212.                                ptrwindow->currentstid, stopelem, TRUE);
  3213.           ptk_inqboundingbox(&area);
  3214. /*
  3215. #endif
  3216. */
  3217.         }
  3218.       }
  3219.     }
  3220.     div = area.x_max - area.x_min;
  3221.     if (div != 0.0)
  3222.       value->x = (point->x - area.x_min)/div;
  3223.     div = area.y_max - area.y_min;
  3224.     if (div != 0.0)
  3225.       value->y = (point->y - area.y_min)/div;
  3226.   }
  3227.   ptk_delstore(store);
  3228.   free(structlist.postings);
  3229.   ptk_unstackbbox();
  3230.   ptk_unstacktsl();
  3231.   return windowfound; 
  3232. }  /* ptk_locscanwindows */
  3233.  
  3234. /*--------------------------------------------------------------------------*/
  3235.  
  3236. /*function:external*/
  3237. extern ptkboolean ptk_scanwindows(C(Pint) wsid, C(ptksgeneralinput *) input, 
  3238.                                C(ptkswindowoutput *) output)
  3239. PreANSI(Pint wsid)
  3240. PreANSI(ptksgeneralinput *input)
  3241. PreANSI(ptkswindowoutput *output)
  3242. /*
  3243. ** \parambegin
  3244. ** \param{Pint}{wsid}{workstation identifier}{IN}
  3245. ** \param{ptksgeneralinput *}{input}{input data}{IN}
  3246. ** \param{ptkswindowoutput *}{output}{output data}{IN}
  3247. ** \paramend
  3248. ** \blurb{This function performs a scan on all posted windows using
  3249. ** either string, pick or locator data.
  3250. ** The function returns TRUE if a window has been selected, 
  3251. ** otherwise FALSE.}
  3252. */
  3253. {
  3254.   ptkboolean result;
  3255.  
  3256.   switch (input->inputclass) 
  3257.   {
  3258.  
  3259.   case PIN_LOC:
  3260.     result = ptk_locscanwindows(wsid, &input->ptkugeninput.locpoint, &output->windowid, &output->windowarea, &output->value);
  3261.     output->measure = TRUE;
  3262.     break;
  3263.  
  3264.   case PIN_STROKE:
  3265.     result = FALSE;
  3266.     break;
  3267.  
  3268.   case PIN_VAL:
  3269.     result = FALSE;
  3270.     break;
  3271.  
  3272.   case PIN_CHOICE:
  3273.     result = FALSE;
  3274.     break;
  3275.  
  3276.   case PIN_PICK:
  3277.     result = ptk_pickscanwindows(&input->ptkugeninput.ptkspickinput.pickdata, 
  3278.                           input->ptkugeninput.ptkspickinput.pathorder,
  3279.                           &output->windowid, &output->windowarea);
  3280.     output->measure = FALSE;
  3281.     break;
  3282.  
  3283.   case PIN_STRING:
  3284.     result = ptk_stringscanwindows(wsid, input->ptkugeninput.str, 
  3285.                                    &output->windowid);
  3286.     output->measure = FALSE;
  3287.     output->windowarea = PTKEWINDOWBANNER;
  3288.     break;
  3289.   }
  3290.   return result;
  3291. }  /* ptk_scanwindows */
  3292.  
  3293. /*--------------------------------------------------------------------------*/
  3294.  
  3295. /*function:external*/
  3296. extern void ptk_inqpostedwindows(C(Pint) wsid, C(Pint) size, 
  3297.                              C(Pint_list *) windowids, C(Pint *) totalsize,
  3298.                              C(Pint *) err)
  3299. PreANSI(Pint wsid)
  3300. PreANSI(Pint size)
  3301. PreANSI(Pint_list *windowids)
  3302. PreANSI(Pint *totalsize)
  3303. PreANSI(Pint *err)
  3304. /*
  3305. ** \parambegin
  3306. ** \param{Pint}{wsid}{workstation identifier}{IN}
  3307. ** \param{Pint}{size}{size of buffer}{IN}
  3308. ** \param{Pint\_list *}{windowids}{list of posted windows}{OUT}
  3309. ** \param{Pint *}{totalsize}{length of posted windows list}{OUT}
  3310. ** \param{Pint *}{err}{error indicator}{OUT}
  3311. ** \paramend
  3312. ** \blurb{This function may be used to obtain a list of all windows
  3313. ** posted to the workstation {\tt wsid}.
  3314. ** The error code is a standard PHIGS error code.}
  3315. */
  3316. {
  3317.   ptkswindow *ptrwindow;
  3318.   Pint numstructs, i;
  3319.   Pposted_struct_list structlist;
  3320.  
  3321.   *err = 0;
  3322.   *totalsize = 0;
  3323.   ptrwindow = firstwind;
  3324.   while (ptrwindow != NULL)
  3325.   {
  3326.     if (ptrwindow->posted && 
  3327.        (ptrwindow->wsid == wsid))
  3328.       (*totalsize)++;
  3329.     ptrwindow = ptrwindow->next;
  3330.   }
  3331.   if (size >= *totalsize)
  3332.   {
  3333.     pinq_posted_structs(wsid, 0, 0, err, &structlist, &numstructs);
  3334.     structlist.postings = (Pposted_struct *)calloc(numstructs, 
  3335.                                               sizeof(Pposted_struct));
  3336.     pinq_posted_structs(wsid, numstructs, 0, err, &structlist, &numstructs);
  3337.     windowids->num_ints = 0;
  3338.     for (i = 0; i < structlist.num_postings; i++)
  3339.     {
  3340.       if (iswindow(structlist.postings[i].id, &ptrwindow))
  3341.       {
  3342.         windowids->ints[windowids->num_ints] = ptrwindow->windowid;
  3343.         windowids->num_ints++;
  3344.       }
  3345.     }
  3346.   }
  3347. }  /* ptk_inqpostedwindows */
  3348.  
  3349. /*--------------------------------------------------------------------------*/
  3350.  
  3351. /*function:external*/
  3352. extern void ptk_inqwindowids(C(Pint) size, C(Pint_list *) windowids, 
  3353.                            C(Pint *) totalsize, C(Pint *) err)
  3354. PreANSI(Pint size)
  3355. PreANSI(Pint_list *windowids)
  3356. PreANSI(Pint *totalsize)
  3357. PreANSI(Pint *err)
  3358. /*
  3359. ** \parambegin
  3360. ** \param{Pint}{size}{size of buffer}{IN}
  3361. ** \param{Pint\_list *}{windowids}{list of windows}{OUT}
  3362. ** \param{Pint *}{totalsize}{length of windows list}{OUT}
  3363. ** \param{Pint *}{err}{error indicator}{OUT}
  3364. ** \paramend
  3365. ** \blurb{This function may be used to obtain a list of all
  3366. ** windows in the PHIGS Toolkit window store.}
  3367. */
  3368. {
  3369.   ptkswindow *ptrwindow;
  3370.  
  3371.   *err = 0;
  3372.   *totalsize = windowcount;
  3373.   if (size >= *totalsize)
  3374.   {
  3375.     windowids->num_ints = 0;
  3376.     ptrwindow = firstwind;
  3377.     while (ptrwindow != NULL)
  3378.     {
  3379.       windowids->ints[windowids->num_ints] = ptrwindow->windowid;
  3380.       windowids->num_ints++;
  3381.       ptrwindow = ptrwindow->next;
  3382.     }
  3383.   }
  3384. }  /* ptk_inqwindowids */
  3385.  
  3386. /*--------------------------------------------------------------------------*/
  3387.  
  3388. /*function:external*/
  3389. extern void ptk_inqwindowstructid(C(Pint) windid, C(Pint *) windowstid, 
  3390.                                   C(Pint *) iconstid, C(Pint *) err)
  3391. PreANSI(Pint windid)
  3392. PreANSI(Pint *windowstid)
  3393. PreANSI(Pint *iconstid)
  3394. PreANSI(Pint *err)
  3395. /*
  3396. ** \parambegin
  3397. ** \param{Pint}{windid}{window identifier}{IN}
  3398. ** \param{Pint *}{windowstid}{window structure identifier}{OUT}
  3399. ** \param{Pint *}{iconstid}{window structure identifier}{OUT}
  3400. ** \param{Pint *}{err}{error indicator}{OUT}
  3401. ** \paramend
  3402. ** \blurb{This function may be used to obtain the identifier of
  3403. ** a window structure and its corresponding icon structure.
  3404. ** The window structure is a network with references to all the items
  3405. ** posted to the window. The default icon is a single structure
  3406. ** containing the window identifier.
  3407. ** The error code = 1 if {\tt windid} doesn't exist.}
  3408. */
  3409. {
  3410.   *err = 0;
  3411.   setwindow(windid);
  3412.   if (windptr != NULL)
  3413.   {
  3414.     *windowstid = windptr->windowstid;
  3415.     *iconstid = windptr->iconstid;
  3416.   }
  3417.   else
  3418.     *err = 1;
  3419. }  /* ptk_inqwindowstructid */
  3420.  
  3421. /*--------------------------------------------------------------------------*/
  3422.  
  3423. /*function:external*/
  3424. extern void ptk_inqwindowname(C(Pint) windid, C(Pint *) name, 
  3425.                             C(Pint *) err) 
  3426. PreANSI(Pint windid)
  3427. PreANSI(Pint *name)
  3428. PreANSI(Pint *err)
  3429. /*
  3430. ** \parambegin
  3431. ** \param{Pint}{windid}{window identifier}{IN}
  3432. ** \param{Pint *}{name}{window name}{OUT}
  3433. ** \param{Pint *}{err}{error indicator}{OUT}
  3434. ** \paramend
  3435. ** \blurb{This function may be used to obtain the window name 
  3436. ** to be used in namesets for the pick, invisibility and 
  3437. ** highlighting filters.
  3438. ** The error code = 1 if {\tt windid} doesn't exist.}
  3439. */
  3440. {
  3441.   *err = 0;
  3442.   setwindow(windid);
  3443.   if (windptr != NULL)
  3444.     *name = windptr->windowname;
  3445.   else
  3446.     *err = 1;
  3447. }  /* ptk_inqwindowname */
  3448.  
  3449. /*--------------------------------------------------------------------------*/
  3450.  
  3451. /*function:external*/
  3452. extern void ptk_inqwindowstate(C(Pint) windid, C(ptkewindowstate *) state, 
  3453.                             C(Pint *) err) 
  3454. PreANSI(Pint windid)
  3455. PreANSI(ptkewindowstate *state)
  3456. PreANSI(Pint *err)
  3457. /*
  3458. ** \parambegin
  3459. ** \param{Pint}{windid}{window identifier}{IN}
  3460. ** \param{ptkewindowstate *}{state}{window state, open or closed}{OUT}
  3461. ** \param{Pint *}{err}{error indicator}{OUT}
  3462. ** \paramend
  3463. ** \blurb{This function may be used to obtain the window state,
  3464. ** open or closed.
  3465. ** The error code = 1 if {\tt windid} doesn't exist.}
  3466. */
  3467. {
  3468.   *err = 0;
  3469.   setwindow(windid);
  3470.   if (windptr != NULL)
  3471.     *state = windptr->windowstate;
  3472.   else
  3473.     *err = 1;
  3474. }  /* ptk_inqwindowstate */
  3475.  
  3476. /*--------------------------------------------------------------------------*/
  3477.  
  3478. /*function:external*/
  3479. extern ptkboolean ptk_inqfrontbackwindowid(C(Pint) wsid, C(Pint *) frontid,
  3480.                 C(ptkewindowstate *) frontstate, C(Pint *) backid, 
  3481.                 C(ptkewindowstate *) backstate, C(Pint *) err)
  3482. PreANSI(Pint wsid)
  3483. PreANSI(Pint *frontid)
  3484. PreANSI(ptkewindowstate *frontstate)
  3485. PreANSI(Pint *backid)
  3486. PreANSI(ptkewindowstate *backstate)
  3487. PreANSI(Pint *err)
  3488. /*
  3489. ** \parambegin
  3490. ** \param{Pint}{wsid}{workstation identifier}{IN}
  3491. ** \param{Pint *}{frontstid}{front window identifier}{OUT}
  3492. ** \param{ptkewindowstate *}{frontstate}{front window state}{OUT}
  3493. ** \param{Pint *}{backstid}{back window identifier}{OUT}
  3494. ** \param{ptkewindowstate *}{backstate}{back window state}{OUT}
  3495. ** \param{Pint *}{err}{error indicator}{OUT}
  3496. ** \paramend
  3497. ** \blurb{This function may be used to obtain the identifiers
  3498. ** of the front and back windows and there current state (OPEN or
  3499. ** CLOSED).}
  3500. */
  3501. {
  3502.   Pint ind;
  3503.  
  3504.   *err = 0;
  3505.   findwsid(wsid, &ind);
  3506.   if (wswindows[ind].postedwindows)
  3507.   {
  3508.     *frontid = wswindows[ind].frontptr->windowid;
  3509.     *frontstate = wswindows[ind].frontptr->windowstate;
  3510.     *backid = wswindows[ind].backptr->windowid;
  3511.     *backstate = wswindows[ind].backptr->windowstate;
  3512.     return TRUE;
  3513.   }
  3514.   else 
  3515.     return FALSE;
  3516. }  /* ptk_inqfrontbackwindowid */
  3517.  
  3518. /*--------------------------------------------------------------------------*/
  3519.  
  3520. /*function:external*/
  3521. extern void ptk_inqwindowposition(C(Pint) windid, C(Ppoint *) position,
  3522.                                   C(Pint *) err) 
  3523. PreANSI(Pint windid)
  3524. PreANSI(Ppoint *position)
  3525. PreANSI(Pint *err)
  3526. /*
  3527. ** \parambegin
  3528. ** \param{Pint}{windid}{window identifier}{IN}
  3529. ** \param{Ppoint *}{position}{window position}{OUT}
  3530. ** \param{Pint *}{err}{error indicator}{OUT}
  3531. ** \paramend
  3532. ** \blurb{This function may be used to obtain the position of the centre
  3533. ** of a window. The position is returned in the range [0, 1].
  3534. ** The error code = 1 if {\tt windid} doesn't exist.}
  3535. */
  3536. {
  3537.   *err = 0;
  3538.   setwindow(windid);
  3539.   if (windptr != NULL)
  3540.     *position = windptr->windowposition;
  3541.   else
  3542.     *err = 1;
  3543. }  /* ptk_inqwindowposition */
  3544.  
  3545. /*--------------------------------------------------------------------------*/
  3546.  
  3547. /*function:external*/
  3548. extern void ptk_inqwindowsize(C(Pint) windid, C(Ppoint *) size, 
  3549.                               C(Pint *) err) 
  3550. PreANSI(Pint windid)
  3551. PreANSI(Ppoint *size)
  3552. PreANSI(Pint *err)
  3553. /*
  3554. ** \parambegin
  3555. ** \param{Pint}{windid}{window identifier}{IN}
  3556. ** \param{Ppoint *}{size}{window size}{OUT}
  3557. ** \param{Pint *}{err}{error indicator}{OUT}
  3558. ** \paramend
  3559. ** \blurb{This function may be used to obtain the size of a window
  3560. ** which is returned in the range [0, 1].
  3561. ** The error code = 1 if {\tt windid} doesn't exist.}
  3562. */
  3563. {
  3564.   *err = 0;
  3565.   setwindow(windid);
  3566.   if (windptr != NULL)
  3567.     *size = windptr->windowsize;
  3568.   else
  3569.     *err = 1;
  3570. }  /* ptk_inqwindowsize */
  3571.  
  3572. /*--------------------------------------------------------------------------*/
  3573.  
  3574. /*function:external*/
  3575. extern void ptk_inqiconposition(C(Pint) windid, C(Ppoint *) position, 
  3576.                                 C(Pint *) err) 
  3577. PreANSI(Pint windid)
  3578. PreANSI(Ppoint *position)
  3579. PreANSI(Pint *err)
  3580. /*
  3581. ** \parambegin
  3582. ** \param{Pint}{windid}{window identifier}{IN}
  3583. ** \param{Ppoint *}{position}{icon position}{OUT}
  3584. ** \param{Pint *}{err}{error indicator}{OUT}
  3585. ** \paramend
  3586. ** \blurb{This function may be used to obtain the position of the centre of 
  3587. ** a window icon which is returned in the range [0, 1].
  3588. ** The error code = 1 if {\tt windid} doesn't exist.}
  3589. */
  3590. {
  3591.   *err = 0;
  3592.   setwindow(windid);
  3593.   if (windptr != NULL)
  3594.     *position = windptr->iconposition;
  3595.   else
  3596.     *err = 1;
  3597. }  /* ptk_inqiconposition */
  3598.  
  3599. /*--------------------------------------------------------------------------*/
  3600.  
  3601. /*function:external*/
  3602. extern void ptk_inqiconsize(C(Pint) windid, C(Ppoint *) size, C(Pint *) err) 
  3603. PreANSI(Pint windid)
  3604. PreANSI(Ppoint *size)
  3605. PreANSI(Pint *err)
  3606. /*
  3607. ** \parambegin
  3608. ** \param{Pint}{windid}{window identifier}{IN}
  3609. ** \param{Ppoint *}{size}{icon size}{OUT}
  3610. ** \param{Pint *}{err}{error indicator}{OUT}
  3611. ** \paramend
  3612. ** \blurb{This function may be used to obtain the size of a window's icon
  3613. ** structure and is returned in the range [0, 1].
  3614. ** The error code = 1 if {\tt windid} doesn't exist.}
  3615. */
  3616. {
  3617.   *err = 0;
  3618.   setwindow(windid);
  3619.   if (windptr != NULL)
  3620.     *size = windptr->iconsize;
  3621.   else
  3622.     *err = 1;
  3623. }  /* ptk_inqiconsize */
  3624.  
  3625. /*--------------------------------------------------------------------------*/
  3626.  
  3627. /*function:external*/
  3628. extern void ptk_inqusericon(C(Pint) windid, C(Pint *) iconstid,
  3629.                              C(Pint *) err) 
  3630. PreANSI(Pint windid)
  3631. PreANSI(Pint *iconstid)
  3632. PreANSI(Pint *err)
  3633. /*
  3634. ** \parambegin
  3635. ** \param{Pint}{windid}{window identifier}{IN}
  3636. ** \param{Pint *}{iconstid}{user icon structure identifier}{OUT}
  3637. ** \param{Pint *}{err}{error indicator}{OUT}
  3638. ** \paramend
  3639. ** \blurb{This function may be used to obtain the identifier of a
  3640. ** user created icon structure. The structure is referenced by the
  3641. ** window's icon structure.
  3642. ** The error code = 1 if {\tt windid} doesn't exist and = 2 if
  3643. ** the default icon is used.}
  3644. */
  3645. {
  3646.   *err = 0;
  3647.   setwindow(windid);
  3648.   if (windptr != NULL)
  3649.   {
  3650.     if (!windptr->defaulticon)
  3651.       *iconstid = windptr->usericon;
  3652.     else
  3653.       *err = 2;
  3654.   }
  3655.   else
  3656.     *err = 1;
  3657. }  /* ptk_inqusericon */
  3658.  
  3659. /*--------------------------------------------------------------------------*/
  3660.  
  3661. /*function:external*/
  3662. extern void ptk_inqframesize(C(Pint) windid, C(Ppoint *) size, 
  3663.                               C(Pint *) err) 
  3664. PreANSI(Pint windid)
  3665. PreANSI(Ppoint *size)
  3666. PreANSI(Pint *err)
  3667. /*
  3668. ** \parambegin
  3669. ** \param{Pint}{windid}{window identifier}{IN}
  3670. ** \param{Ppoint *}{size}{frame size}{OUT}
  3671. ** \param{Pint *}{err}{error indicator}{OUT}
  3672. ** \paramend
  3673. ** \blurb{This function may be used to obtain the dimensions of the
  3674. ** window frame. They are returned in the range [0, 1] and the default
  3675. ** dimensions are (0.01, 0.01).
  3676. ** The error code = 1 if {\tt windid} doesn't exist.}
  3677. */
  3678. {
  3679.   *err = 0;
  3680.   setwindow(windid);
  3681.   if (windptr != NULL)
  3682.     *size = windptr->framesize;
  3683.   else
  3684.     *err = 1;
  3685. }  /* ptk_inqframesize */
  3686.  
  3687. /*--------------------------------------------------------------------------*/
  3688.  
  3689. /*function:external*/
  3690. extern void ptk_inqwindowtype(C(Pint) windid, C(ptkewindowtype *) type, 
  3691.                               C(Pint *) err) 
  3692. PreANSI(Pint windid)
  3693. PreANSI(ptkewindowtype *type)
  3694. PreANSI(Pint *err)
  3695. /*
  3696. ** \parambegin
  3697. ** \param{Pint}{windid}{window identifier}{IN}
  3698. ** \param{ptkewindowtype *}{type}{window type}{OUT}
  3699. ** \param{Pint *}{err}{error indicator}{OUT}
  3700. ** \paramend
  3701. ** \blurb{This function may be used to inquire the type of a window.
  3702. ** The available types are STRUCT, TOPOLOGY, CONTENT and TERMINAL.
  3703. ** The default window type is STRUCT and may be used to view any PHIGS
  3704. ** structures.
  3705. ** The error code = 1 if {\tt windid} doesn't exist.}
  3706. */
  3707. {
  3708.   *err = 0;
  3709.   setwindow(windid);
  3710.   if (windptr != NULL)
  3711.     *type = windptr->windowtype;
  3712.   else
  3713.     *err = 1;
  3714. }  /* ptk_inqwindowtype */
  3715.  
  3716. /*--------------------------------------------------------------------------*/
  3717.  
  3718. /*function:external*/
  3719. extern void ptk_inqwindowattrs(C(Pint) windid,
  3720.       C(Pint *) titlefont, C(Pint *) titlecolour, C(Pint *) bannercolour,
  3721.       C(Pint *) backgdcolour, C(Pint *) edgecolour, 
  3722.       C(Pint *) frametlcolour, C(Pint *) framebrcolour, C(Pint *) err)
  3723. PreANSI(Pint windid)
  3724. PreANSI(Pint *titlefont)
  3725. PreANSI(Pint *titlecolour)
  3726. PreANSI(Pint *bannercolour)
  3727. PreANSI(Pint *backgdcolour)
  3728. PreANSI(Pint *edgecolour)
  3729. PreANSI(Pint *frametlcolour)
  3730. PreANSI(Pint *framebrcolour)
  3731. PreANSI(Pint *err)
  3732. /* 
  3733. ** \parambegin
  3734. ** \param{Pint}{windid}{window identifier}{IN}
  3735. ** \param{Pint *}{titlefont}{title string font}{OUT}
  3736. ** \param{Pint *}{titlecolour}{title string colour index}{OUT}
  3737. ** \param{Pint *}{bannercolour}{banner colour index}{OUT}
  3738. ** \param{Pint *}{backgdcolour}{background colour index of window}{OUT}
  3739. ** \param{Pint *}{edgecolour}{edge colour index of window}{OUT}
  3740. ** \param{Pint *}{frametlcolour}{top-left frame colour index}{OUT}
  3741. ** \param{Pint *}{framebrcolour}{bottom-right frame colour index}{OUT}
  3742. ** \param{Pint *}{err}{error indicator}{OUT}
  3743. ** \paramend
  3744. ** \blurb{This function may be used to obtain the text font and
  3745. ** colour attribute values of a window.
  3746. ** The error code = 1 if {\tt windid} doesn't exist.}
  3747. */
  3748. {   
  3749.   *err = 0;
  3750.   setwindow(windid);
  3751.   if (windptr != NULL)
  3752.   {  
  3753.     *titlefont = windptr->titlefont;
  3754.     *titlecolour = windptr->titlecolour;  
  3755.     *bannercolour = windptr->bannercolour;
  3756.     *backgdcolour = windptr->backgdcolour;
  3757.     *edgecolour = windptr->edgecolour;
  3758.     *frametlcolour = windptr->frametlcolour;
  3759.     *framebrcolour = windptr->framebrcolour;
  3760.   }
  3761.   else
  3762.     *err = 1;
  3763. }  /* ptk_inqwindowattrs */
  3764.  
  3765. /*--------------------------------------------------------------------------*/
  3766. /*-------------------------- icon functions --------------------------------*/
  3767. /*--------------------------------------------------------------------------*/
  3768.  
  3769. /*function:external*/
  3770. extern void ptk_seticonposition(C(Pint) windid, C(Ppoint *) position)
  3771. PreANSI(Pint windid)
  3772. PreANSI(Ppoint *position)
  3773. /*
  3774. ** \parambegin
  3775. ** \param{Pint}{windid}{window identifier}{IN}
  3776. ** \param{Ppoint *}{position}{icon position}{IN}
  3777. ** \paramend 
  3778. ** \blurb{This function sets the position of the centre of the 
  3779. ** window's icon structure. The position is given in the range [0, 1].}
  3780. */
  3781.   setwindow(windid);
  3782.   if (windptr != NULL)
  3783.   {
  3784.     if ((position->x > 0.0) && (position->x < 1.0) &&
  3785.         (position->y > 0.0) && (position->y < 1.0))
  3786.     {
  3787.       windptr->iconposition = *position;
  3788.       updateicon();
  3789.     }
  3790.   }
  3791. }  /* ptk_seticonposition */
  3792.  
  3793. /*--------------------------------------------------------------------------*/
  3794.  
  3795. /*function:external*/
  3796. extern void ptk_seticonsize(C(Pint) windid, C(Ppoint *) size)
  3797. PreANSI(Pint windid)
  3798. PreANSI(Ppoint *size)
  3799. /*
  3800. ** \parambegin
  3801. ** \param{Pint}{windid}{window identifier}{IN}
  3802. ** \param{Ppoint *}{size}{icon size}{IN}
  3803. ** \paramend 
  3804. ** \blurb{This function sets the size of the window's icon structure.
  3805. ** The size is given in the range [0, 1].}
  3806. */
  3807. {
  3808.   setwindow(windid);
  3809.   if (windptr != NULL)
  3810.   {
  3811.     if ((size->x > 0.0) && (size->y > 0.0))
  3812.     {  
  3813.       windptr->iconsize = *size;
  3814.       updateicon();
  3815.     }
  3816.   }
  3817. }  /* ptk_seticonsize */
  3818.  
  3819. /*--------------------------------------------------------------------------*/
  3820.  
  3821. /*function:external*/
  3822. extern void ptk_setusericon(C(Pint) windid, C(Pint) usericon)
  3823. PreANSI(Pint windid)
  3824. PreANSI(Pint usericon)
  3825. /*
  3826. ** \parambegin
  3827. ** \param{Pint}{windid}{window identifier}{IN}
  3828. ** \param{Pint}{user icon}{icon structure identifier}{IN}
  3829. ** \paramend 
  3830. ** \blurb{This function enables the application to specify a structure
  3831. ** identifier to use as a window icon. The structure is executed from
  3832. ** the window's default icon structure and the icon size and position
  3833. ** functions still apply provided the user icon is defined within
  3834. ** the World Coordinate range [0, 1].}
  3835. */
  3836. {
  3837.   setwindow(windid);
  3838.   if (windptr != NULL)
  3839.   {
  3840.     if (windptr->defaulticon)
  3841.     {
  3842.       ptk_openstruct(windptr->iconstid);
  3843.       pset_elem_ptr(0);
  3844.       pdel_elems_labels(ptk_stringtoint("label", "begin-icon"), 
  3845.                       ptk_stringtoint("label", "end-icon"));  
  3846.       ptk_seteditmode(PEDIT_INSERT);
  3847.       pexec_struct(usericon);
  3848.       ptk_unseteditmode();
  3849.       ptk_closestruct(); 
  3850.       windptr->defaulticon = FALSE;
  3851.     }
  3852.   }
  3853. }  /* ptk_setusericon */
  3854.  
  3855. /*--------------------------------------------------------------------------*/
  3856. /*------------------------- banner functions -------------------------------*/
  3857.  
  3858. /*function:external*/
  3859. extern void ptk_setbannercolours(C(Pint) windid, C(Pint) bannercolour, 
  3860.                                C(Pint) titlecolour)
  3861. PreANSI(Pint windid)
  3862. PreANSI(Pint bannercolour)
  3863. PreANSI(Pint titlecolour)
  3864. /*
  3865. ** \parambegin
  3866. ** \param{Pint}{windid}{window identifier}{IN}
  3867. ** \param{Pint}{bannercolour}{banner colour index}{IN}
  3868. ** \param{Pint}{titlecolour}{title string colour index}{IN}
  3869. ** \paramend 
  3870. ** \blurb{This function sets the colour indicies of a window banner.
  3871. ** It is useful for highlighting a current window, for example
  3872. ** in a `point and click' window system.}
  3873. */
  3874. {
  3875.   setwindow(windid);
  3876.   if (windptr != NULL)
  3877.   {
  3878.     windptr->bannercolour = bannercolour;
  3879.     windptr->titlecolour = titlecolour;
  3880.     updateframe();
  3881.   }
  3882. }  /* ptk_setbannercolours */
  3883.  
  3884. /*--------------------------------------------------------------------------*/
  3885.  
  3886. /*function:external*/
  3887. extern void ptk_setbannerheight(C(Pint) windid, C(Pfloat) bannerheight)
  3888. PreANSI(Pint windid)
  3889. PreANSI(Pfloat bannerheight)
  3890. /*
  3891. ** \parambegin
  3892. ** \param{Pint}{windid}{window identifier}{IN}
  3893. ** \param{Pfloat}{bannerheight}{height of banner}{IN}
  3894. ** \paramend 
  3895. ** \blurb{This function sets the height of the window banner to
  3896. ** {\tt bannerheight} which is given in the range [0, 1]. The window
  3897. ** title is re-scaled to fit the new height.}
  3898. */
  3899. {
  3900.   setwindow(windid);
  3901.   if (windptr != NULL)
  3902.   {
  3903.     windptr->bannerheight = bannerheight;
  3904.     updateframe();
  3905.   }
  3906. }  /* ptk_setbannerheight */
  3907.  
  3908. /*--------------------------------------------------------------------------*/
  3909.  
  3910. /*function:external*/
  3911. extern void ptk_inqbannerheight(C(Pint) windid, C(Pfloat *) bannerheight,
  3912.                                 C(Pint *) err)
  3913. PreANSI(Pint windid)
  3914. PreANSI(Pfloat *bannerheight)
  3915. PreANSI(Pint *err)
  3916. /*
  3917. ** \parambegin
  3918. ** \param{Pint}{windid}{window identifier}{IN}
  3919. ** \param{Pfloat *}{bannerheight}{height of banner}{OUT}
  3920. ** \param{Pint *}{err}{error indicator}{OUT}
  3921. ** \paramend 
  3922. ** \blurb{This function may be used to obtain the height of a window
  3923. ** banner. It is returned in the range [0, 1].
  3924. ** The error code = 1 if {\tt windid} doesn't exist.}
  3925. */
  3926. {
  3927.   *err = 0;
  3928.   setwindow(windid);
  3929.   if (windptr != NULL)
  3930.     *bannerheight = windptr->bannerheight;
  3931.   else
  3932.     *err = 1;
  3933. }  /* ptk_inqbannerheight */
  3934.  
  3935. /*--------------------------------------------------------------------------*/
  3936.  
  3937. /*function:external*/
  3938. extern void ptk_setbannertitle(C(Pint) windid, C(char *) titlestring)
  3939. PreANSI(Pint windid)
  3940. PreANSI(char *titlestring)
  3941. /*
  3942. ** \parambegin
  3943. ** \param{Pint}{windid}{window identifier}{IN}
  3944. ** \param{char *}{titlestring}{title string of window banner}{IN}
  3945. ** \paramend 
  3946. ** \blurb{This function sets the title string of a window. The title
  3947. ** is displayed in the window banner and is automatically scaled to
  3948. ** fit inside the banner area.}
  3949. */
  3950. {
  3951.   setwindow(windid);
  3952.   if (windptr != NULL)
  3953.   {  
  3954.     strncpy(windptr->titlestring, titlestring, strlen(titlestring) + 1);
  3955.     updateframe();
  3956.   }
  3957. }  /* ptk_setbannertitle */
  3958.  
  3959. /*--------------------------------------------------------------------------*/
  3960.  
  3961. /*function:external*/
  3962. extern void ptk_inqbannertitle(C(Pint) windid, C(Pint) len,
  3963.                     C(char *) titlestr, C(Pint *) totlen, C(Pint *) err)
  3964. PreANSI(Pint windid)
  3965. PreANSI(Pint len)
  3966. PreANSI(char *titlestr)
  3967. PreANSI(Pint *totlen)
  3968. PreANSI(Pint *err)
  3969. /*
  3970. ** \parambegin
  3971. ** \param{Pint}{windid}{window identifier}{IN}
  3972. ** \param{Pint}{len}{length of string}{IN}
  3973. ** \param{char *}{titlestr}{title string of banner}{IN}
  3974. ** \param{Pint *}{totlen}{actual length of string}{OUT}
  3975. ** \param{Pint *}{err}{error indicator}{OUT}
  3976. ** \paramend 
  3977. ** \blurb{This function may be used to obtain the title of a window.
  3978. ** The error code = 1 if {\tt windid} doesn't exist.}
  3979. */
  3980. {
  3981.   *err = 0;
  3982.   setwindow(windid);
  3983.   if (windptr != NULL)
  3984.   {  
  3985.     *totlen = strlen(windptr->titlestring) + 1;
  3986.     if (len >= *totlen)
  3987.       strncpy(titlestr, windptr->titlestring, *totlen);
  3988.   }
  3989.   else
  3990.     *err = 1;
  3991. }  /* ptk_inqbannertitle */
  3992.  
  3993. /*--------------------------------------------------------------------------*/
  3994. /*---------------------- Terminal window functions -------------------------*/
  3995. /*--------------------------------------------------------------------------*/
  3996.  
  3997. static void addline(C(char *) line, C(Pedit_mode) edtype)
  3998. PreANSI(char *line)
  3999. PreANSI(Pedit_mode edtype)
  4000. /*
  4001. ** \parambegin
  4002. ** \param{}{termnum}{index to terminal window array}{IN}
  4003. ** \param{}{line}{line to add or replace}{IN}
  4004. ** \param{}{edtype}{edit mode}{IN}
  4005. ** \paramend
  4006. ** \blurb{Updates the PHIGS structure containing the terminal window
  4007. ** text. Either replaces the last line or inserts a new one.}
  4008. */
  4009. {
  4010.   Ppoint textpos;
  4011.   Pint i;
  4012.  
  4013.   /* initialise ptr to last elem */
  4014.   /* remove old text elements from structure */
  4015.   ptk_openstruct(windptr->term.textstid);
  4016.   poffset_elem_ptr(-1);
  4017.   ptk_seteditmode(edtype);
  4018.  
  4019.   /* insert new text element */
  4020.   i = windptr->term.curr_line;
  4021.   textpos = ptk_point(ptkctmlinespace,
  4022.                       -(Pfloat)i * windptr->term.increment);
  4023.   ptext(&textpos, line);
  4024.   ptk_unseteditmode();
  4025.   ptk_closestruct();
  4026. }  /* addline */
  4027.  
  4028. /*--------------------------------------------------------------------------*/
  4029.  
  4030. static void setterminalline()
  4031. {
  4032.   Pfloat oneline;
  4033.  
  4034.   /* view orientation */
  4035.   oneline = -windptr->windowsize.y/(Pfloat)windptr->term.lines;
  4036.   windptr->vrp = ptk_point3(0.0, -windptr->windowsize.y + 
  4037.                    (oneline * (Pfloat)(windptr->term.visline - 1)), 0.0);
  4038.   /* set view rep */
  4039.   updateview();
  4040. }  /* setterminalline */
  4041.  
  4042. /*--------------------------------------------------------------------------*/
  4043.  
  4044. /*function:external*/
  4045. extern void ptk_scrollterminal(C(Pint) windid, C(Ptext_path) scrolldir,
  4046.                            C(Pint) numlines)
  4047. PreANSI(Pint windid)
  4048. PreANSI(Ptext_path scrolldir)
  4049. PreANSI(Pint numlines)
  4050. /*
  4051. ** \parambegin
  4052. ** \param{}{windid}{terminal window identifier}{IN}
  4053. ** \param{}{scrolldir}{scroll direction (up or down)}{IN}
  4054. ** \param{}{numlines}{number of lines to scroll by}{IN}
  4055. ** \paramend
  4056. ** \blurb{This function scrolls the contents of the TERMINAL window
  4057. ** either UP or DOWN by {\tt numlines}.}
  4058. */
  4059. {
  4060.   setwindow(windid);
  4061.   if (windptr != NULL)
  4062.   {
  4063.     if (windptr->windowtype == PTKETERMINALWINDOW)
  4064.     {
  4065.       switch (scrolldir)
  4066.       {
  4067.       case PPATH_DOWN: 
  4068.         windptr->term.visline -= numlines;  
  4069.         break;
  4070.     
  4071.       case PPATH_UP:
  4072.         windptr->term.visline += numlines;
  4073.         break;
  4074.     
  4075.       case PPATH_LEFT:
  4076.         break;
  4077.     
  4078.       case PPATH_RIGHT:
  4079.         break;
  4080.       }
  4081.       setterminalline();
  4082.     }
  4083.   }
  4084. }  /* ptk_scrollterminal */
  4085.  
  4086. /*--------------------------------------------------------------------------*/
  4087.  
  4088. /*function:external*/
  4089. extern void ptk_setterminaldata(C(Pint) windid, C(Pint) numlines,
  4090.                                 C(Pint) txfont, C(Pint) txcolour)
  4091. PreANSI(Pint windid)
  4092. PreANSI(Pint numlines)
  4093. PreANSI(Pint txfont)
  4094. PreANSI(Pint txcolour)
  4095. /*
  4096. ** \parambegin
  4097. ** \param{Pint}{windid}{terminal window identifier}{IN}
  4098. ** \param{Pint}{numlines}{number of lines in window}{IN}
  4099. ** \param{Pint}{numcolmns}{number of columns in window}{IN}
  4100. ** \param{Pint}{txfont}{text font}{IN}
  4101. ** \param{Pint}{txcolour}{text colour}{IN}
  4102. ** \paramend
  4103. ** \blurb{This function sets the number of lines to be displayed in a 
  4104. ** TERMINAL window and which text font and colour to use.}
  4105. */
  4106. {
  4107.   char stname[30];
  4108.   Pint termnum, err, wstype;
  4109.   Pfloat linespace, chrht, textheight, textwidth;
  4110.   Ptext_align align;
  4111.   void *connid;
  4112.   Prect rect;
  4113.   Ppoint offset;
  4114.   Pfloat wwidth, wheight, charheight, charwidth, lineheight;
  4115.   Pstore store;
  4116.  
  4117.   setwindow(windid);
  4118.   if (windptr != NULL)
  4119.   {
  4120.     if (windptr->windowtype == PTKETERMINALWINDOW)
  4121.     {
  4122.       windptr->term.lines = numlines;
  4123.     
  4124.       /* create structure with appropriate attr */
  4125.       pempty_struct(windptr->term.textstid);
  4126.       ptk_openstruct(windptr->term.textstid);
  4127.     
  4128.       /* user specified font*/
  4129.       windptr->term.txfont = txfont;
  4130.       windptr->term.txcolour = txcolour;
  4131.       pset_text_font(txfont);
  4132.       pset_text_colr_ind(txcolour);
  4133.       align.hor = PHOR_NORM;
  4134.       align.vert = PVERT_BOTTOM;
  4135.       pset_text_align(&align);
  4136.       /* size characters so they all fit within window */
  4137.       textwidth = windptr->windowsize.x * 0.99;
  4138.       textheight = windptr->windowsize.y * 0.9;
  4139.       linespace = (windptr->windowsize.y * 0.1)/(Pfloat)windptr->term.lines;
  4140.  
  4141.       /* character height */
  4142.       /* Implementation dependent bit because HP and PEXSI doesn't support
  4143.       ** INQUIRE TEXT EXTENT. For HP and PEXSI assume font 1.
  4144.       */
  4145. #ifdef SUN
  4146.       pcreate_store(&err, &store);
  4147.       pinq_ws_conn_type(windptr->wsid, store, &err, &connid, &wstype);
  4148.       pinq_text_extent(wstype, txfont, 1.0, 0.0, 0.01, PPATH_RIGHT, 
  4149.         PHOR_NORM, PVERT_NORM, "W", &err, &rect, &offset);
  4150. #endif
  4151. #ifdef HP
  4152.       rect.p = ptk_point(0.0, 0.0);
  4153.       rect.q = ptk_point(0.01, 0.015);
  4154. #endif
  4155. #ifdef PEXSI
  4156.       rect.p = ptk_point(0.0, 0.0);
  4157.       rect.q = ptk_point(0.01, 0.015);
  4158. #endif
  4159.  
  4160.       wheight = rect.q.y - rect.p.y;
  4161.       wwidth = rect.q.x - rect.p.x;
  4162.       
  4163.       lineheight = textheight / (Pfloat)numlines;
  4164.       charheight = 0.01 * (lineheight / wheight);
  4165.       charwidth = wwidth * (lineheight / wheight);
  4166.       pset_char_ht(charheight);
  4167.       windptr->term.increment = textheight/(Pfloat)windptr->term.lines 
  4168.                                  + linespace;
  4169.       windptr->term.realcols = textwidth / charwidth;
  4170.       windptr->term.columns = (Pint)windptr->term.realcols;
  4171.       windptr->term.reallines = (Pfloat)numlines;
  4172.       plabel(ptk_stringtoint("label", "$tm_starttext"));
  4173.       /* put text elements here */
  4174.       plabel(ptk_stringtoint("label", "$tm_endtext"));
  4175.       ptk_closestruct();
  4176.       ptk_delstore(store);
  4177.     }
  4178.   }
  4179. }  /* ptk_setterminaldata */
  4180.  
  4181. /*--------------------------------------------------------------------------*/
  4182.  
  4183. /*function:external*/
  4184. extern void ptk_inqterminaldata(C(Pint) windid, C(Pint *) numlines,
  4185.             C(Pint *) numcolms, C(Pint *) txfont, C(Pint *) txcolour,
  4186.             C(Pint *) err)
  4187. PreANSI(Pint windid)
  4188. PreANSI(Pint *numlines)
  4189. PreANSI(Pint *numcolms)
  4190. PreANSI(Pint *txfont)
  4191. PreANSI(Pint *txcolour)
  4192. PreANSI(Pint *err)
  4193. /*
  4194. ** \parambegin
  4195. ** \param{Pint}{windid}{terminal window identifier}{IN}
  4196. ** \param{Pint *}{numlines}{number of lines in window}{OUT}
  4197. ** \param{Pint *}{numcolmns}{number of columns in window}{OUT}
  4198. ** \param{Pint *}{txfont}{text font}{OUT}
  4199. ** \param{Pint *}{txcolour}{text colour}{OUT}
  4200. ** \param{Pint *}{err}{error indicator}{OUT}
  4201. ** \paramend
  4202. ** \blurb{This function may be used to obtain the number of lines
  4203. ** displayed in a TERMINAL window and the number of characters in a line.
  4204. ** Also the text font and colour used are returned in {\tt txfont} and
  4205. ** {\tt txcolour}. The error code = 1 if {\tt windid} doesn't exist
  4206. ** and = 2 if it is not a terminal window.}
  4207. */
  4208. {
  4209.   *err = 0;
  4210.   setwindow(windid);
  4211.   if (windptr != NULL)
  4212.   {
  4213.     if (windptr->windowtype == PTKETERMINALWINDOW)
  4214.     {
  4215.       *numlines = windptr->term.lines;    
  4216.       *numcolms = windptr->term.columns;    
  4217.       *txfont = windptr->term.txfont;
  4218.       *txcolour = windptr->term.txcolour;
  4219.     }
  4220.     else
  4221.       *err = 2;
  4222.   }
  4223.   else
  4224.     *err = 1;
  4225. }  /* ptk_inqterminaldata */
  4226.  
  4227. /*--------------------------------------------------------------------------*/
  4228.  
  4229. /*function:external*/
  4230. extern void ptk_refreshterminal(C(Pint) windid)
  4231. PreANSI(Pint windid)
  4232. /*
  4233. ** \parambegin
  4234. ** \param{Pint}{windid}{terminal window identifier}{IN}
  4235. ** \paramend
  4236. ** \blurb{This function refreshes the TERMINAL window so that the
  4237. ** last text line is visible.}
  4238. */
  4239. {
  4240.   Pint linediff;
  4241.  
  4242.   /* show updates */
  4243.   setwindow(windid);
  4244.   if (windptr != NULL)
  4245.   {
  4246.     if (windptr->windowtype == PTKETERMINALWINDOW)
  4247.     {
  4248.       linediff = windptr->term.curr_line - windptr->term.visline;
  4249.       if (abs(linediff) >= windptr->term.lines)
  4250.       {
  4251.         windptr->term.visline = windptr->term.curr_line - 
  4252.                                 windptr->term.lines + 1; 
  4253.         setterminalline();
  4254.       }
  4255.     }
  4256.   }
  4257. }  /* ptk_refreshterminal */
  4258.  
  4259. /*--------------------------------------------------------------------------*/
  4260.  
  4261. /*function:external*/
  4262. extern void ptk_writeterminal(C(Pint) windid, C(char *) str)
  4263. PreANSI(Pint windid)
  4264. PreANSI(char *str)
  4265. /*
  4266. ** \parambegin
  4267. ** \param{Pint}{windid}{terminal window identifier}{IN}
  4268. ** \param{char *}{str}{string to write to window}{IN}
  4269. ** \paramend
  4270. ** \blurb{This function writes a character string to the current line
  4271. ** of the TERMINAL window. A new line is started when the end of the
  4272. ** current line is reached.}
  4273. */
  4274.   Pint wtlen, spaceleft, stringleft, allocsize;
  4275.   Pint cpylen;
  4276.   char *templine;
  4277.   Pint termnum;
  4278.   Pedit_mode emode;
  4279.  
  4280.   setwindow(windid);
  4281.   if (windptr != NULL)
  4282.   {
  4283.     if (windptr->windowtype == PTKETERMINALWINDOW)
  4284.     {
  4285.       templine = windptr->term.lastline;
  4286.     
  4287.       /* length of string to write */
  4288.       wtlen = strlen(str);
  4289.     
  4290.       /* number of character spaces left on current line */
  4291.       spaceleft = windptr->term.columns - windptr->term.curr_colm;
  4292.     
  4293.       /* add into current line if possible */
  4294.     
  4295.       if (spaceleft > 0)
  4296.       {
  4297.         /* allocate space for line */
  4298.         if (wtlen > spaceleft)
  4299.           /* spans more than one line */
  4300.           allocsize = windptr->term.columns + 1;
  4301.         else
  4302.           /* fits entirely on current line */
  4303.           allocsize = windptr->term.curr_colm + wtlen + 1;
  4304.         if (templine == NULL)
  4305.         {
  4306.           templine = (char *)malloc(allocsize);
  4307.           emode = PEDIT_INSERT;
  4308.         }
  4309.         else
  4310.         {
  4311.           templine = (char *)realloc(windptr->term.lastline, allocsize);
  4312.           emode = PEDIT_REPLACE;
  4313.         }
  4314.     
  4315.         /* cpylen = min(wtlen, spaceleft) */
  4316.         cpylen = wtlen < spaceleft ? wtlen : spaceleft;
  4317.     
  4318.         /* copy as much of str as possible into current line */
  4319.         strncpy(&templine[windptr->term.curr_colm], 
  4320.                 str, cpylen);
  4321.     
  4322.         windptr->term.curr_colm = allocsize - 1;
  4323.         templine[allocsize - 1] = '\0';   
  4324.         addline(templine, emode);
  4325.       }
  4326.     
  4327.       stringleft = wtlen - spaceleft;
  4328.     
  4329.       while (stringleft > 0)
  4330.       {
  4331.         /* create a new line */
  4332.         /* allocate space for line */
  4333.     
  4334.         if (stringleft > windptr->term.columns)
  4335.           allocsize = windptr->term.columns + 1;
  4336.         else
  4337.           allocsize = stringleft + 1;
  4338.         free(templine);
  4339.         templine = NULL;
  4340.         templine = (char *)malloc(sizeof(char) * allocsize);
  4341.           
  4342.         /* copy as much of string as possible */
  4343.         strncpy(templine, &str[wtlen - stringleft], 
  4344.                 allocsize); 
  4345.         windptr->term.curr_line++;
  4346.         windptr->term.curr_colm = allocsize - 1;
  4347.         templine[allocsize - 1] = '\0';
  4348.         stringleft -= windptr->term.columns;
  4349.         addline(templine, PEDIT_INSERT);
  4350.    
  4351.       }  /* while */
  4352.  
  4353.       windptr->term.lastline = templine;
  4354.  
  4355.       ptk_refreshterminal(windid);
  4356.     }
  4357.   }
  4358. }  /* ptk_writeterminal */
  4359.  
  4360. /*--------------------------------------------------------------------------*/
  4361.  
  4362. /*function:external*/
  4363. extern void ptk_writelnterminal(C(Pint) windid, C(char *) str)
  4364. PreANSI(Pint windid)
  4365. PreANSI(char *str)
  4366. /*
  4367. ** \parambegin
  4368. ** \param{Pint}{windid}{terminal window identifier}{IN}
  4369. ** \param{char *}{str}{string to write to window}{IN}
  4370. ** \paramend
  4371. ** \blurb{This function writes a character string to the current line
  4372. ** of the TERMINAL window. A new line is started when the end of the current
  4373. ** line is reached and at the next call to a TERMINAL write function.}
  4374. */
  4375. {
  4376.   setwindow(windid);
  4377.   if (windptr != NULL)
  4378.   {
  4379.     if (windptr->windowtype == PTKETERMINALWINDOW)
  4380.     {    
  4381.       ptk_writeterminal(windid, str);
  4382.       /* goto end of line */
  4383.       windptr->term.curr_colm = windptr->term.columns;
  4384.     }
  4385.   }
  4386. }  /* ptk_writelnterminal */
  4387.  
  4388. /*--------------------------------------------------------------------------*/
  4389.  
  4390. /*function:external*/
  4391. extern void ptk_printfterminal(C(Pint) windid, C(char *) format, va_alist)
  4392. PreANSI(Pint windid)
  4393. PreANSI(char *format)
  4394. va_dcl
  4395. /*
  4396. ** \parambegin
  4397. ** \param{Pint}{windid}{terminal window identifier}{IN}
  4398. ** \param{char *}{format}{format string}{IN}
  4399. ** \param{}{va\_alist}{variable length argument list}{IN}
  4400. ** \paramend
  4401. ** \blurb{This function writes to a TERMINAL window using a variable length
  4402. ** argument list and a format string like the C printf function.}
  4403. */
  4404. {
  4405.   va_list args;
  4406.   char str[255], line[255];
  4407.   char *newline, *firstchar;
  4408.  
  4409.   va_start(args);
  4410.   vsprintf(str, format, args);
  4411.   va_end(args);
  4412.  
  4413.   firstchar = &str[0];
  4414.   while ((newline = strchr(firstchar, '\n')) != NULL)
  4415.   {
  4416.     strncpy(line, firstchar, (newline - firstchar)); 
  4417.     line[newline - firstchar] = '\0';
  4418.     ptk_writelnterminal(windid, line);
  4419.     firstchar = newline + 1;
  4420.   }
  4421.  
  4422.   if (firstchar != '\0')
  4423.     ptk_writeterminal(windid, firstchar);
  4424. }  /* ptk_printfterminal */
  4425.  
  4426. /*--------------------------------------------------------------------------*/
  4427.  
  4428. /*function:external*/
  4429. extern void ptk_clearterminal(C(Pint) windid)
  4430. PreANSI(Pint windid)
  4431. /*
  4432. ** \parambegin
  4433. ** \param{Pint}{windid}{terminal window identifier}{IN}
  4434. ** \paramend
  4435. ** \blurb{This function empties the structure containing all the text
  4436. ** written to the TERMINAL window.}
  4437. */
  4438. {
  4439.   setwindow(windid);
  4440.   if (windptr != NULL)
  4441.   {
  4442.     if (windptr->windowtype == PTKETERMINALWINDOW)
  4443.     {
  4444.       /* first clear out PHIGS structure */
  4445.       ptk_openstruct(windptr->term.textstid);
  4446.       pset_elem_ptr(0);
  4447.       pdel_elems_labels(ptk_stringtoint("label", "$tm_starttext"),
  4448.                       ptk_stringtoint("label", "$tm_endtext"));
  4449.       ptk_closestruct();
  4450.       predraw_all_structs(windptr->wsid, PFLAG_ALWAYS);
  4451.   
  4452.       /* now clear out data structure */
  4453.       windptr->term.curr_line = 0;
  4454.       windptr->term.curr_colm = windptr->term.columns;
  4455.       windptr->term.visline = 0;
  4456.   
  4457.       free(windptr->term.lastline);
  4458.       windptr->term.lastline = NULL;
  4459.       ptk_scrollterminal(windid, PPATH_UP, 1);
  4460.     }
  4461.   }
  4462. }  /* ptk_clearterminal */
  4463.  
  4464. /*--------------------------------------------------------------------------*/
  4465.  
  4466. /*function:external*/
  4467. extern void ptk_writeintterminal(C(Pint) windid, C(Pint) number)
  4468. PreANSI(Pint windid)
  4469. PreANSI(Pint number)
  4470. /*
  4471. ** \parambegin
  4472. ** \param{Pint}{windid}{terminal window identifier}{IN}
  4473. ** \param{Pint}{number}{integer to write to window}{IN}
  4474. ** \paramend
  4475. ** \blurb{This function writes an integer to a TERMINAL window.}
  4476. */
  4477. {
  4478.   char intstr[81];
  4479.  
  4480.   sprintf(intstr, "%d", number);
  4481.   ptk_writeterminal(windid, intstr);
  4482. }  /* ptk_writeintterminal */
  4483.  
  4484. /*--------------------------------------------------------------------------*/
  4485.  
  4486. /*function:external*/
  4487. extern void ptk_writefloatterminal(C(Pint) windid, C(Pfloat) number)
  4488. PreANSI(Pint windid)
  4489. PreANSI(Pfloat number)
  4490. /*
  4491. ** \parambegin
  4492. ** \param{Pint}{windid}{terminal window identifier}{IN}
  4493. ** \param{Pfloat}{number}{float number to write to window}{IN}
  4494. ** \paramend
  4495. ** \blurb{This function writes a floating point number to a TERMINAL window.}
  4496. */
  4497. {
  4498.   char floatstr[81];
  4499.  
  4500.   setwindow(windid);
  4501.   if (windptr != NULL)
  4502.   {
  4503.     if (windptr->windowtype == PTKETERMINALWINDOW)
  4504.     {
  4505.       sprintf(floatstr, windptr->term.floatformat, number);
  4506.       ptk_writeterminal(windid, floatstr);
  4507.     }
  4508.   }
  4509. }  /* ptk_writefloatterminal */
  4510.  
  4511. /*--------------------------------------------------------------------------*/
  4512.  
  4513. /*function:external*/
  4514. extern void ptk_setterminalfloatformat(C(Pint) windid, C(char *) rformat)
  4515. PreANSI(Pint windid)
  4516. PreANSI(char *rformat)
  4517. /*
  4518. ** \parambegin
  4519. ** \param{Pint}{windid}{terminal window identifier}{IN}
  4520. ** \param{char *}{rformat}{string giving C-type float number output style}{IN}
  4521. ** \paramend
  4522. ** \blurb{This function sets the format for writing floating-point numbers
  4523. ** to a TERMINAL window. The format used is the same syntax as in the
  4524. ** C language.}
  4525. */
  4526. {
  4527.   Pint rlen;
  4528.  
  4529.   setwindow(windid);
  4530.   if (windptr != NULL)
  4531.   {
  4532.     if (windptr->windowtype == PTKETERMINALWINDOW)
  4533.     {
  4534.       rlen = strlen(rformat);
  4535.       if (rlen > ptkcfloatformat) 
  4536.         rlen = ptkcfloatformat; 
  4537.       strncpy(windptr->term.floatformat, rformat, (rlen + 1));
  4538.     }
  4539.   }
  4540. }  /* ptk_setterminalfloatformat */
  4541.  
  4542. /*--------------------------------------------------------------------------*/
  4543.  
  4544. /*function:external*/
  4545. extern void ptk_inqterminalfloatformat(C(Pint) windid, C(Pint) size, 
  4546.             C(Pint *) totalsize, C(char *) rformat, C(Pint *) err)
  4547. PreANSI(Pint windid)
  4548. PreANSI(Pint size)
  4549. PreANSI(Pint *totalsize)
  4550. PreANSI(char *rformat)
  4551. PreANSI(Pint *err)
  4552. /*
  4553. ** \parambegin
  4554. ** \param{Pint}{windid}{terminal window identifier}{IN}
  4555. ** \param{Pint}{size}{size of buffer, in bytes, as allocated by application}{IN}
  4556. ** \param{Pint *}{totalsize}{actual size of buffer}{IN}
  4557. ** \param{char *}{rformat}{string giving C-type float number output style}{IN}
  4558. ** \param{Pint *}{err}{error indicator}{OUT}
  4559. ** \paramend
  4560. ** \blurb{This function may be used to obtain the floating-point used
  4561. ** for writing floating-point numbers to a TERMINAL window.
  4562. ** The error code = 1 if {\tt windid} doesn't exist and = 2 if it is
  4563. ** not a terminal window.}
  4564. */
  4565. {
  4566.   *err = 0;
  4567.   setwindow(windid);
  4568.   if (windptr != NULL)
  4569.   {
  4570.     if (windptr->windowtype == PTKETERMINALWINDOW)
  4571.     {
  4572.       *totalsize = strlen(windptr->term.floatformat) + 1;
  4573.       if (size >= *totalsize)
  4574.       {
  4575.         strncpy(rformat, windptr->term.floatformat, *totalsize);
  4576.         rformat[*totalsize - 1] = '\0';
  4577.       }
  4578.     }
  4579.     else
  4580.       *err = 2;
  4581.   }
  4582.   else
  4583.     *err = 1;
  4584. }  /* ptk_inqterminalfloatformat */
  4585.  
  4586. /*--------------------------------------------------------------------------*/
  4587.  
  4588. /*function:external*/
  4589. extern void ptk_inqterminalstructid(C(Pint) windid, C(Pint *) termtextstid,
  4590.             C(Pint *) err)
  4591. PreANSI(Pint windid)
  4592. PreANSI(Pint *termtextstid)
  4593. PreANSI(Pint *err)
  4594. /*
  4595. ** \parambegin
  4596. ** \param{Pint}{windid}{terminal window identifier}{IN}
  4597. ** \param{Pint *}{rformat}{string giving C-type real number output style}{IN}
  4598. ** \param{Pint *}{err}{error indicator}{OUT}
  4599. ** \paramend
  4600. ** \blurb{This function may be used to obtain the identifier of the
  4601. ** structure used to display the text written to a TERMINAL window.
  4602. ** The error code = 1 if {\tt windid} doesn't exist and = 2 if it is
  4603. ** not a terminal window.}
  4604. */
  4605. {
  4606.   *err = 0;
  4607.   setwindow(windid);
  4608.   if (windptr != NULL)
  4609.   {
  4610.     if (windptr->windowtype == PTKETERMINALWINDOW)
  4611.       *termtextstid = windptr->term.textstid;
  4612.     else
  4613.       *err = 2;
  4614.   }
  4615.   else
  4616.     *err = 1;
  4617. }  /* ptk_inqterminalstructid */
  4618.  
  4619. /*--------------------------------------------------------------------------*/
  4620. /*----------------------- Topology window functions ------------------------*/
  4621. /*--------------------------------------------------------------------------*/
  4622.  
  4623. /*function:external*/
  4624. extern void ptk_settopologyviewarea(C(Pint) windid, C(Plimit *) viewarea)
  4625. PreANSI(Pint windid)
  4626. PreANSI(Plimit *viewarea)
  4627. /*
  4628. ** \parambegin
  4629. ** \param{Pint}{windid}{window identifier}{IN}
  4630. ** \param{Plimit *}{viewarea}{area of topology to view}{IN}
  4631. ** \paramend 
  4632. ** \blurb{This function sets the viewing area of a topology diagram posted
  4633. ** to a TOPOLOGY window. The area is defined in the range [0, 1].}
  4634. */
  4635. {
  4636.   setwindow(windid);
  4637.   if (windptr != NULL)
  4638.   {
  4639.     if (windptr->windowtype == PTKETOPOLOGYWINDOW)
  4640.     {
  4641.       /* calculate aspect ratio of window */
  4642.       windptr->topviewarea = windptr->win = *viewarea;
  4643.       windptr->proj_ref_point.x = windptr->win.x_min + 
  4644.                        (windptr->win.x_max - windptr->win.x_min) / 2.0;
  4645.       windptr->proj_ref_point.y = windptr->win.y_min + 
  4646.                        (windptr->win.y_max - windptr->win.y_min) / 2.0;
  4647.       updateview();
  4648.     }
  4649.   }
  4650. }  /* ptk_settopologyviewarea */
  4651.  
  4652. /*--------------------------------------------------------------------------*/
  4653.  
  4654. /*function:external*/
  4655. extern void ptk_inqtopologyviewarea(C(Pint) windid, C(Plimit *) viewarea,
  4656.                                     C(Pint *) err)
  4657. PreANSI(Pint windid)
  4658. PreANSI(Plimit *viewarea)
  4659. PreANSI(Pint *err)
  4660. /*
  4661. ** \parambegin
  4662. ** \param{Pint}{windid}{window identifier}{IN}
  4663. ** \param{Plimit *}{viewarea}{area of topology to view}{OUT}
  4664. ** \param{Pint *}{err}{error indicator}{OUT}
  4665. ** \paramend 
  4666. ** \blurb{This function may be used to obtain the viewing area
  4667. ** of a topology diagram posted to a TOPOLOGY window.
  4668. ** The error code = 1 if {\tt windid} doesn't exist and = 2 if it is
  4669. ** not a topology window.}
  4670. */
  4671. {
  4672.   *err = 0;
  4673.   setwindow(windid);
  4674.   if (windptr != NULL)
  4675.   {
  4676.     if (windptr->windowtype == PTKETOPOLOGYWINDOW)
  4677.       *viewarea = windptr->topviewarea;
  4678.     else
  4679.       *err = 2;
  4680.   }
  4681.   else
  4682.     *err = 1;
  4683. }  /* ptk_inqtopologyviewarea */
  4684.  
  4685. /*--------------------------------------------------------------------------*/
  4686. /*----------------------- Content window functions -------------------------*/
  4687. /*--------------------------------------------------------------------------*/
  4688.  
  4689. /*function:external*/
  4690. extern void ptk_setcontentviewrange(C(Pint) windid, C(Pint) range1, 
  4691.                                     C(Pint) range2)
  4692. PreANSI(Pint windid)
  4693. PreANSI(Pint range1)
  4694. PreANSI(Pint range2)
  4695. /*
  4696. ** \parambegin
  4697. ** \param{Pint}{windid}{window identifier}{IN}
  4698. ** \param{Pint}{range1}{start element number}{IN}
  4699. ** \param{Pint}{range2}{end element number}{IN}
  4700. ** \paramend 
  4701. ** \blurb{This function sets the range of elements of a structure
  4702. ** content diagram to view in a CONTENT window.}
  4703. */
  4704. {
  4705.   Pfloat projht, projwt, winht, winwt, aspectratio, winaspectratio;
  4706.   Pfloat diff, elemspace, fudge;
  4707.   Pint numelems, first, last, viewelems;
  4708.  
  4709.   setwindow(windid);
  4710.   if (windptr != NULL)
  4711.   {
  4712.     if (windptr->windowtype == PTKECONTENTWINDOW)
  4713.     {
  4714.       /* check range is valid */
  4715.       first = range1;
  4716.       last = range2;
  4717.       if (range1 < 0)
  4718.         first = windptr->range1;
  4719.       if ((range2 > windptr->range2) || (range2 == 0))
  4720.         last = windptr->range2;
  4721.       if (last < first)
  4722.         last = first;
  4723.  
  4724.       windptr->viewrange1 = first;
  4725.       windptr->viewrange2 = last;
  4726.       /* calculate window given element range to view */
  4727.       numelems = windptr->range2 - windptr->range1 + 2;
  4728.      
  4729.       if (numelems < 10) 
  4730.         elemspace = 0.1;
  4731.       else
  4732.         elemspace = 1.0 / (Pfloat)numelems;
  4733.       fudge = 0.01/(Pfloat)numelems;
  4734.       windptr->win.y_max = 1.0 - ((Pfloat)(first - windptr->range1 + 1) * 
  4735.                                     elemspace);
  4736.       windptr->win.y_min = 1.0 - ((Pfloat)(last - windptr->range1 + 2) * 
  4737.                                     elemspace) - fudge;
  4738.       windptr->win.x_min = 0.0;
  4739.       viewelems = last - first + 1;
  4740.       if (viewelems < 10)
  4741.         viewelems = 10;
  4742.       if (numelems < 10) 
  4743.         windptr->win.x_max = 1.0;
  4744.       else
  4745.         windptr->win.x_max = (Pfloat)viewelems / (Pfloat)numelems;
  4746.       /* calculate aspect ratio of window */
  4747.       projht = windptr->win.y_max - windptr->win.y_min;
  4748.       projwt = windptr->win.x_max - windptr->win.x_min;
  4749.       aspectratio = projht / projwt;
  4750.   
  4751.       /* adjust view area to have same aspect ratio as window */
  4752.       windptr->viewbox = windptr->proj_vp = windptr->viewlims;
  4753.       winht = windptr->proj_vp.y_max - windptr->proj_vp.y_min;
  4754.       winwt = windptr->proj_vp.x_max - windptr->proj_vp.x_min;
  4755.       winaspectratio = winht / winwt;
  4756.       
  4757.       if (aspectratio > winaspectratio)
  4758.       {
  4759.         /* decrease x */
  4760.         diff = (winwt - ((1.0 / aspectratio) * winht));
  4761.         windptr->proj_vp.x_max -= diff;
  4762.       }
  4763.       else
  4764.       if (aspectratio < winaspectratio)
  4765.       {
  4766.         /* decrease y */
  4767.         diff = (winht - (aspectratio * winwt));
  4768.         windptr->proj_vp.y_min += diff;
  4769.       }       
  4770.  
  4771.       windptr->proj_ref_point = ptk_point3(
  4772.         (windptr->win.x_max - windptr->win.x_min) / 2.0, 
  4773.         (windptr->win.y_min +
  4774.          (windptr->win.y_max - windptr->win.y_min) / 2.0), 2.0);
  4775.  
  4776.       updateview();
  4777.     }
  4778.   }
  4779. }  /* ptk_setcontentviewrange */
  4780.  
  4781. /*--------------------------------------------------------------------------*/
  4782.  
  4783. /*function:external*/
  4784. extern void ptk_inqcontentviewrange(C(Pint) windid, C(Pint *) range1, 
  4785.                                 C(Pint *) range2, C(Pint *) err)
  4786. PreANSI(Pint windid)
  4787. PreANSI(Pint *range1)
  4788. PreANSI(Pint *range2)
  4789. PreANSI(Pint *err)
  4790. /*
  4791. ** \parambegin
  4792. ** \param{Pint}{windid}{terminal window identifier}{IN}
  4793. ** \param{Pint}{range1}{element number}{IN}
  4794. ** \param{Pint}{range2}{element number}{IN}
  4795. ** \param{Pint *}{err}{error indicator}{OUT}
  4796. ** \paramend
  4797. ** \blurb{This function may be used to obtain the viewing range of
  4798. ** a structure content diagram which is posted to a CONTENT window.
  4799. ** The error code = 1 if {\tt windid} doesn't exist and = 2 if it is
  4800. ** not a content window.}
  4801. */
  4802. {
  4803.   *err = 0;
  4804.   setwindow(windid);
  4805.   if (windptr != NULL)
  4806.   {
  4807.     if (windptr->windowtype == PTKECONTENTWINDOW)
  4808.     {
  4809.       *range1 = windptr->viewrange1;
  4810.       *range2 = windptr->viewrange2;
  4811.     }
  4812.     else
  4813.       *err = 2;
  4814.   }
  4815.   else
  4816.     *err = 1;
  4817. }  /* ptk_inqcontentviewrange */
  4818.  
  4819. /*--------------------------------------------------------------------------*/
  4820. /*----------------------- Window type functions ----------------------------*/
  4821. /*--------------------------------------------------------------------------*/
  4822.  
  4823. /*function:external*/
  4824. extern void ptk_setwindowtype(C(Pint) windid, C(ptkewindowtype) windtype)
  4825. PreANSI(Pint windid)
  4826. PreANSI(ptkewindowtype windtype)
  4827. /*
  4828. ** \parambegin
  4829. ** \param{Pint}{windid}{window identifier}{IN}
  4830. ** \param{ptkewindowtype}{windtype}{window type}{IN}
  4831. ** \paramend 
  4832. ** \blurb{This function sets the type of a window to one of
  4833. ** STRUCT, TOPOLOGY, CONTENT and TERMINAL. The default window type is
  4834. ** STRUCT. All items are unposted from the window before the type
  4835. ** is set.}
  4836. */
  4837. {
  4838.   char stname[20];
  4839.  
  4840.   setwindow(windid);
  4841.   if (windptr != NULL)
  4842.   {
  4843.     windptr->windowtype = windtype;
  4844.     ptk_unpostallfromwindow(windid);
  4845.     switch (windtype)
  4846.     {
  4847.     case PTKESTRUCTWINDOW:
  4848.       /* change icon */
  4849.       ptk_openstruct(windptr->iconstid);
  4850.       pset_elem_ptr(0);
  4851.       pdel_elems_labels(ptk_stringtoint("label", "begin-icon-pic"), 
  4852.                       ptk_stringtoint("label", "end-icon"));  
  4853.       ptk_seteditmode(PEDIT_INSERT);
  4854.       do_structicon();
  4855.       ptk_unseteditmode();
  4856.       ptk_closestruct(); 
  4857.       break;
  4858.   
  4859.     case PTKETERMINALWINDOW:
  4860.       /* create a text structure */
  4861.       sprintf(stname, "ptk$term%d", windid);
  4862.       windptr->term.textstid = ptk_stringtoint("structureid", stname);
  4863.   
  4864.       /* post to window */
  4865.       ptk_openstruct(windptr->windowstid);
  4866.       ptk_seteditmode(PEDIT_INSERT);
  4867.       pset_elem_ptr(0);
  4868.       pset_elem_ptr_label(ptk_stringtoint("label", "begin-window"));
  4869.       pexec_struct(windptr->term.textstid);    
  4870.       ptk_unseteditmode();
  4871.       ptk_closestruct();
  4872.   
  4873.       /* initialise */
  4874.       windptr->term.curr_line = 0;
  4875.       windptr->term.visline = 0;
  4876.       strncpy(windptr->term.floatformat, "%.5e", 5);
  4877.       windptr->term.lastline = NULL;
  4878.       ptk_setterminaldata(windid, 20, 1, 1);
  4879.       windptr->term.curr_colm = windptr->term.columns;
  4880.       /* initialise view */
  4881.       windptr->cameraswitch = PTKECAMERAOFF;
  4882.       initialiseterminal();
  4883.       ptk_scrollterminal(windid, PPATH_UP, 1);
  4884.  
  4885.       /* change icon */
  4886.       ptk_openstruct(windptr->iconstid);
  4887.       pset_elem_ptr(0);
  4888.       pdel_elems_labels(ptk_stringtoint("label", "begin-icon-pic"), 
  4889.                       ptk_stringtoint("label", "end-icon"));  
  4890.       ptk_seteditmode(PEDIT_INSERT);
  4891.       do_terminalicon();
  4892.       ptk_unseteditmode();
  4893.       ptk_closestruct(); 
  4894.       break;
  4895.   
  4896.     case PTKETOPOLOGYWINDOW:
  4897.       windptr->proj_vp = ptk_limit3(0.0, 1.0, 0.0, 1.0, 0.0, 1.0);  
  4898.       /* default viewing variables */
  4899.       windptr->proj_type = PTYPE_PARAL;
  4900.       windptr->vrp = ptk_point3(0.0, 0.0, 0.0);
  4901.       windptr->proj_ref_point = ptk_point3(0.5, 0.5, 2.0);
  4902.       windptr->vpn = ptk_point3(0.0, 0.0, 1.0);
  4903.       windptr->vup = ptk_point3(0.0, 1.0, 0.0);
  4904.       windptr->topviewarea = windptr->win = ptk_limit(0.0, 1.0, 0.0, 1.0);
  4905.       windptr->viewplane = windptr->frontplane = 1.0;
  4906.       windptr->backplane = 0.0;
  4907.   
  4908.       /* other window defaults */
  4909.       windptr->cameraswitch = PTKECAMERAOFF;
  4910.       updateview();
  4911.  
  4912.       /* change icon */
  4913.       ptk_openstruct(windptr->iconstid);
  4914.       pset_elem_ptr(0);
  4915.       pdel_elems_labels(ptk_stringtoint("label", "begin-icon-pic"), 
  4916.                       ptk_stringtoint("label", "end-icon"));  
  4917.       ptk_seteditmode(PEDIT_INSERT);
  4918.       do_topologyicon();
  4919.       ptk_unseteditmode();
  4920.       ptk_closestruct(); 
  4921.       break;
  4922.   
  4923.     case PTKECONTENTWINDOW:
  4924.       windptr->cliplimit = windptr->viewlims;
  4925.       /* default viewing variables */
  4926.       windptr->proj_type = PTYPE_PARAL;
  4927.       windptr->vrp = ptk_point3(0.0, 0.0, 0.0);
  4928.       windptr->proj_ref_point = ptk_point3(0.5, 0.5, 2.0);
  4929.       windptr->vpn = ptk_point3(0.0, 0.0, 1.0);
  4930.       windptr->vup = ptk_point3(0.0, 1.0, 0.0);
  4931.       windptr->win = ptk_limit(0.0, 1.0, 0.0, 1.0);
  4932.       windptr->viewplane = windptr->frontplane = 1.0;
  4933.       windptr->backplane = 0.0;
  4934.       
  4935.       /* other window defaults */
  4936.       windptr->cameraswitch = PTKECAMERAOFF;
  4937.       updateview();
  4938.  
  4939.       /* change icon */
  4940.       ptk_openstruct(windptr->iconstid);
  4941.       pset_elem_ptr(0);
  4942.       pdel_elems_labels(ptk_stringtoint("label", "begin-icon-pic"), 
  4943.                       ptk_stringtoint("label", "end-icon"));  
  4944.       ptk_seteditmode(PEDIT_INSERT);
  4945.       do_contenticon();
  4946.       ptk_unseteditmode();
  4947.       ptk_closestruct(); 
  4948.       break;
  4949.     }
  4950.   }
  4951. }  /* ptk_setwindowtype */
  4952.  
  4953. /*--------------------------------------------------------------------------*/
  4954.  
  4955. /* end of wind.c */
  4956.  
  4957.